1 ; RUN: llc -mtriple=i386-linux-gnu %s -o - | FileCheck %s -check-prefix=i386
2 ; RUN: llc -mtriple=i386-linux-gnu -pre-RA-sched=fast %s -o - | FileCheck %s -check-prefix=i386f
4 ; RUN: llc -mtriple=x86_64-linux-gnu %s -o - | FileCheck %s -check-prefix=x8664
5 ; RUN: llc -mtriple=x86_64-linux-gnu -pre-RA-sched=fast %s -o - | FileCheck %s -check-prefix=x8664
6 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+sahf %s -o - | FileCheck %s -check-prefix=x8664-sahf
7 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+sahf -pre-RA-sched=fast %s -o - | FileCheck %s -check-prefix=x8664-sahf
8 ; RUN: llc -mtriple=x86_64-linux-gnu -mcpu=corei7 %s -o - | FileCheck %s -check-prefix=x8664-sahf
10 ; TODO: Reenable verify-machineinstr once the if (!AXDead) // FIXME
11 ; in X86InstrInfo::copyPhysReg() is resolved.
16 define i64 @test_intervening_call(i64* %foo, i64 %bar, i64 %baz) {
17 ; i386-LABEL: test_intervening_call:
19 ; i386-NEXT: pushl %eax
22 ; i386-NEXT: movl %eax, [[FLAGS:%.*]]
23 ; i386-NEXT: popl %eax
24 ; i386-NEXT: movl %edx, 4(%esp)
25 ; i386-NEXT: movl %eax, (%esp)
26 ; i386-NEXT: calll bar
27 ; i386-NEXT: movl [[FLAGS]], %eax
28 ; i386-NEXT: addb $127, %al
32 ; i386f-LABEL: test_intervening_call:
34 ; i386f-NEXT: movl %eax, (%esp)
35 ; i386f-NEXT: movl %edx, 4(%esp)
36 ; i386f-NEXT: seto %al
38 ; i386f-NEXT: movl %eax, [[FLAGS:%.*]]
39 ; i386f-NEXT: calll bar
40 ; i386f-NEXT: movl [[FLAGS]], %eax
41 ; i386f-NEXT: addb $127, %al
45 ; x8664-LABEL: test_intervening_call:
48 ; x8664-NEXT: popq [[FLAGS:%.*]]
49 ; x8664-NEXT: movq %rax, %rdi
50 ; x8664-NEXT: callq bar
51 ; x8664-NEXT: pushq [[FLAGS]]
55 ; x8664-sahf-LABEL: test_intervening_call:
56 ; x8664-sahf: cmpxchgq
57 ; x8664-sahf: pushq %rax
58 ; x8664-sahf-NEXT: seto %al
59 ; x8664-sahf-NEXT: lahf
60 ; x8664-sahf-NEXT: movq %rax, [[FLAGS:%.*]]
61 ; x8664-sahf-NEXT: popq %rax
62 ; x8664-sahf-NEXT: movq %rax, %rdi
63 ; x8664-sahf-NEXT: callq bar
64 ; x8664-sahf-NEXT: pushq %rax
65 ; x8664-sahf-NEXT: movq [[FLAGS]], %rax
66 ; x8664-sahf-NEXT: addb $127, %al
67 ; x8664-sahf-NEXT: sahf
68 ; x8664-sahf-NEXT: popq %rax
69 ; x8664-sahf-NEXT: jne
71 %cx = cmpxchg i64* %foo, i64 %bar, i64 %baz seq_cst seq_cst
72 %v = extractvalue { i64, i1 } %cx, 0
73 %p = extractvalue { i64, i1 } %cx, 1
75 br i1 %p, label %t, label %f
84 ; Interesting in producing a clobber without any function calls.
85 define i32 @test_control_flow(i32* %p, i32 %i, i32 %j) {
86 ; i386-LABEL: test_control_flow:
90 ; i386f-LABEL: test_control_flow:
94 ; x8664-LABEL: test_control_flow:
98 ; x8664-sahf-LABEL: test_control_flow:
100 ; x8664-sahf-NEXT: jne
103 %cmp = icmp sgt i32 %i, %j
104 br i1 %cmp, label %loop_start, label %cond.end
107 br label %while.condthread-pre-split.i
109 while.condthread-pre-split.i:
110 %.pr.i = load i32, i32* %p, align 4
111 br label %while.cond.i
114 %0 = phi i32 [ %.pr.i, %while.condthread-pre-split.i ], [ 0, %while.cond.i ]
115 %tobool.i = icmp eq i32 %0, 0
116 br i1 %tobool.i, label %while.cond.i, label %while.body.i
119 %.lcssa = phi i32 [ %0, %while.cond.i ]
120 %1 = cmpxchg i32* %p, i32 %.lcssa, i32 %.lcssa seq_cst seq_cst
121 %2 = extractvalue { i32, i1 } %1, 1
122 br i1 %2, label %cond.end.loopexit, label %while.condthread-pre-split.i
128 %cond = phi i32 [ %i, %entry ], [ 0, %cond.end.loopexit ]
132 ; This one is an interesting case because CMOV doesn't have a chain
133 ; operand. Naive attempts to limit cmpxchg EFLAGS use are likely to fail here.
134 define i32 @test_feed_cmov(i32* %addr, i32 %desired, i32 %new) {
135 ; i386-LABEL: test_feed_cmov:
137 ; i386-NEXT: seto %al
139 ; i386-NEXT: movl %eax, [[FLAGS:%.*]]
140 ; i386-NEXT: calll foo
141 ; i386-NEXT: pushl %eax
142 ; i386-NEXT: movl [[FLAGS]], %eax
143 ; i386-NEXT: addb $127, %al
145 ; i386-NEXT: popl %eax
147 ; i386f-LABEL: test_feed_cmov:
149 ; i386f-NEXT: seto %al
151 ; i386f-NEXT: movl %eax, [[FLAGS:%.*]]
152 ; i386f-NEXT: calll foo
153 ; i386f-NEXT: pushl %eax
154 ; i386f-NEXT: movl [[FLAGS]], %eax
155 ; i386f-NEXT: addb $127, %al
157 ; i386f-NEXT: popl %eax
159 ; x8664-LABEL: test_feed_cmov:
162 ; x8664-NEXT: popq [[FLAGS:%.*]]
163 ; x8664-NEXT: callq foo
164 ; x8664-NEXT: pushq [[FLAGS]]
167 ; x8664-sahf-LABEL: test_feed_cmov:
168 ; x8664-sahf: cmpxchgl
169 ; x8664-sahf: pushq %rax
170 ; x8664-sahf-NEXT: seto %al
171 ; x8664-sahf-NEXT: lahf
172 ; x8664-sahf-NEXT: movq %rax, [[FLAGS:%.*]]
173 ; x8664-sahf-NEXT: popq %rax
174 ; x8664-sahf-NEXT: callq foo
175 ; x8664-sahf-NEXT: pushq %rax
176 ; x8664-sahf-NEXT: movq [[FLAGS]], %rax
177 ; x8664-sahf-NEXT: addb $127, %al
178 ; x8664-sahf-NEXT: sahf
179 ; x8664-sahf-NEXT: popq %rax
181 %res = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst
182 %success = extractvalue { i32, i1 } %res, 1
184 %rhs = call i32 @foo()
186 %ret = select i1 %success, i32 %new, i32 %rhs