CodeGen: Redo analyzePhysRegs() and computeRegisterLiveness()
[oota-llvm.git] / test / CodeGen / X86 / cmpxchg-clobber-flags.ll
1 ; RUN: llc -verify-machineinstrs -mtriple=i386-linux-gnu %s -o - | FileCheck %s -check-prefix=i386
2 ; RUN: llc -verify-machineinstrs -mtriple=i386-linux-gnu -pre-RA-sched=fast %s -o - | FileCheck %s -check-prefix=i386f
3
4 ; RUN: llc -verify-machineinstrs -mtriple=x86_64-linux-gnu %s -o - | FileCheck %s -check-prefix=x8664
5 ; RUN: llc -verify-machineinstrs -mtriple=x86_64-linux-gnu -pre-RA-sched=fast %s -o - | FileCheck %s -check-prefix=x8664
6 ; RUN: llc -verify-machineinstrs -mtriple=x86_64-linux-gnu -mattr=+sahf %s -o - | FileCheck %s -check-prefix=x8664-sahf
7 ; RUN: llc -verify-machineinstrs -mtriple=x86_64-linux-gnu -mattr=+sahf -pre-RA-sched=fast %s -o - | FileCheck %s -check-prefix=x8664-sahf
8 ; RUN: llc -verify-machineinstrs -mtriple=x86_64-linux-gnu -mcpu=corei7 %s -o - | FileCheck %s -check-prefix=x8664-sahf
9
10 declare i32 @foo()
11 declare i32 @bar(i64)
12
13 define i64 @test_intervening_call(i64* %foo, i64 %bar, i64 %baz) {
14 ; i386-LABEL: test_intervening_call:
15 ; i386: cmpxchg8b
16 ; i386-NEXT: pushl %eax
17 ; i386-NEXT: seto %al
18 ; i386-NEXT: lahf
19 ; i386-NEXT: movl %eax, [[FLAGS:%.*]]
20 ; i386-NEXT: popl %eax
21 ; i386-NEXT: movl %edx, 4(%esp)
22 ; i386-NEXT: movl %eax, (%esp)
23 ; i386-NEXT: calll bar
24 ; i386-NEXT: movl [[FLAGS]], %eax
25 ; i386-NEXT: addb $127, %al
26 ; i386-NEXT: sahf
27 ; i386-NEXT: jne
28
29 ; i386f-LABEL: test_intervening_call:
30 ; i386f: cmpxchg8b
31 ; i386f-NEXT: movl %eax, (%esp)
32 ; i386f-NEXT: movl %edx, 4(%esp)
33 ; i386f-NEXT: seto %al
34 ; i386f-NEXT: lahf
35 ; i386f-NEXT: movl %eax, [[FLAGS:%.*]]
36 ; i386f-NEXT: calll bar
37 ; i386f-NEXT: movl [[FLAGS]], %eax
38 ; i386f-NEXT: addb $127, %al
39 ; i386f-NEXT: sahf
40 ; i386f-NEXT: jne
41
42 ; x8664-LABEL: test_intervening_call:
43 ; x8664: cmpxchgq
44 ; x8664: pushfq
45 ; x8664-NEXT: popq [[FLAGS:%.*]]
46 ; x8664-NEXT: movq %rax, %rdi
47 ; x8664-NEXT: callq bar
48 ; x8664-NEXT: pushq [[FLAGS]]
49 ; x8664-NEXT: popfq
50 ; x8664-NEXT: jne
51
52 ; x8664-sahf-LABEL: test_intervening_call:
53 ; x8664-sahf: cmpxchgq
54 ; x8664-sahf: pushq %rax
55 ; x8664-sahf-NEXT: seto %al
56 ; x8664-sahf-NEXT: lahf
57 ; x8664-sahf-NEXT: movq %rax, [[FLAGS:%.*]]
58 ; x8664-sahf-NEXT: popq %rax
59 ; x8664-sahf-NEXT: movq %rax, %rdi
60 ; x8664-sahf-NEXT: callq bar
61 ; x8664-sahf-NEXT: movq [[FLAGS]], %rax
62 ; x8664-sahf-NEXT: addb $127, %al
63 ; x8664-sahf-NEXT: sahf
64 ; x8664-sahf-NEXT: jne
65
66   %cx = cmpxchg i64* %foo, i64 %bar, i64 %baz seq_cst seq_cst
67   %v = extractvalue { i64, i1 } %cx, 0
68   %p = extractvalue { i64, i1 } %cx, 1
69   call i32 @bar(i64 %v)
70   br i1 %p, label %t, label %f
71
72 t:
73   ret i64 42
74
75 f:
76   ret i64 0
77 }
78
79 ; Interesting in producing a clobber without any function calls.
80 define i32 @test_control_flow(i32* %p, i32 %i, i32 %j) {
81 ; i386-LABEL: test_control_flow:
82 ; i386: cmpxchg
83 ; i386-NEXT: jne
84
85 ; i386f-LABEL: test_control_flow:
86 ; i386f: cmpxchg
87 ; i386f-NEXT: jne
88
89 ; x8664-LABEL: test_control_flow:
90 ; x8664: cmpxchg
91 ; x8664-NEXT: jne
92
93 ; x8664-sahf-LABEL: test_control_flow:
94 ; x8664-sahf: cmpxchg
95 ; x8664-sahf-NEXT: jne
96
97 entry:
98   %cmp = icmp sgt i32 %i, %j
99   br i1 %cmp, label %loop_start, label %cond.end
100
101 loop_start:
102   br label %while.condthread-pre-split.i
103
104 while.condthread-pre-split.i:
105   %.pr.i = load i32, i32* %p, align 4
106   br label %while.cond.i
107
108 while.cond.i:
109   %0 = phi i32 [ %.pr.i, %while.condthread-pre-split.i ], [ 0, %while.cond.i ]
110   %tobool.i = icmp eq i32 %0, 0
111   br i1 %tobool.i, label %while.cond.i, label %while.body.i
112
113 while.body.i:
114   %.lcssa = phi i32 [ %0, %while.cond.i ]
115   %1 = cmpxchg i32* %p, i32 %.lcssa, i32 %.lcssa seq_cst seq_cst
116   %2 = extractvalue { i32, i1 } %1, 1
117   br i1 %2, label %cond.end.loopexit, label %while.condthread-pre-split.i
118
119 cond.end.loopexit:
120   br label %cond.end
121
122 cond.end:
123   %cond = phi i32 [ %i, %entry ], [ 0, %cond.end.loopexit ]
124   ret i32 %cond
125 }
126
127 ; This one is an interesting case because CMOV doesn't have a chain
128 ; operand. Naive attempts to limit cmpxchg EFLAGS use are likely to fail here.
129 define i32 @test_feed_cmov(i32* %addr, i32 %desired, i32 %new) {
130 ; i386-LABEL: test_feed_cmov:
131 ; i386: cmpxchgl
132 ; i386-NEXT: seto %al
133 ; i386-NEXT: lahf
134 ; i386-NEXT: movl %eax, [[FLAGS:%.*]]
135 ; i386-NEXT: calll foo
136 ; i386-NEXT: pushl %eax
137 ; i386-NEXT: movl [[FLAGS]], %eax
138 ; i386-NEXT: addb $127, %al
139 ; i386-NEXT: sahf
140 ; i386-NEXT: popl %eax
141
142 ; i386f-LABEL: test_feed_cmov:
143 ; i386f: cmpxchgl
144 ; i386f-NEXT: seto %al
145 ; i386f-NEXT: lahf
146 ; i386f-NEXT: movl %eax, [[FLAGS:%.*]]
147 ; i386f-NEXT: calll foo
148 ; i386f-NEXT: pushl %eax
149 ; i386f-NEXT: movl [[FLAGS]], %eax
150 ; i386f-NEXT: addb $127, %al
151 ; i386f-NEXT: sahf
152 ; i386f-NEXT: popl %eax
153
154 ; x8664-LABEL: test_feed_cmov:
155 ; x8664: cmpxchg
156 ; x8664: pushfq
157 ; x8664-NEXT: popq [[FLAGS:%.*]]
158 ; x8664-NEXT: callq foo
159 ; x8664-NEXT: pushq [[FLAGS]]
160 ; x8664-NEXT: popfq
161
162 ; x8664-sahf-LABEL: test_feed_cmov:
163 ; x8664-sahf: cmpxchgl
164 ; x8664-sahf: seto %al
165 ; x8664-sahf-NEXT: lahf
166 ; x8664-sahf-NEXT: movq %rax, [[FLAGS:%.*]]
167 ; x8664-sahf-NEXT: callq foo
168 ; x8664-sahf-NEXT: pushq %rax
169 ; x8664-sahf-NEXT: movq [[FLAGS]], %rax
170 ; x8664-sahf-NEXT: addb $127, %al
171 ; x8664-sahf-NEXT: sahf
172 ; x8664-sahf-NEXT: popq %rax
173
174   %res = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
175   %success = extractvalue { i32, i1 } %res, 1
176
177   %rhs = call i32 @foo()
178
179   %ret = select i1 %success, i32 %new, i32 %rhs
180   ret i32 %ret
181 }