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