xref: /aosp_15_r20/external/llvm/test/Transforms/GVN/atomic.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -basicaa -gvn -S < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
4*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-apple-macosx10.7.0"
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Worker@x = common global i32 0, align 4
7*9880d681SAndroid Build Coastguard Worker@y = common global i32 0, align 4
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Worker; GVN across unordered store (allowed)
10*9880d681SAndroid Build Coastguard Workerdefine i32 @test1() nounwind uwtable ssp {
11*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test1
12*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %x, %x
13*9880d681SAndroid Build Coastguard Workerentry:
14*9880d681SAndroid Build Coastguard Worker  %x = load i32, i32* @y
15*9880d681SAndroid Build Coastguard Worker  store atomic i32 %x, i32* @x unordered, align 4
16*9880d681SAndroid Build Coastguard Worker  %y = load i32, i32* @y
17*9880d681SAndroid Build Coastguard Worker  %z = add i32 %x, %y
18*9880d681SAndroid Build Coastguard Worker  ret i32 %z
19*9880d681SAndroid Build Coastguard Worker}
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker; GVN across unordered load (allowed)
22*9880d681SAndroid Build Coastguard Workerdefine i32 @test3() nounwind uwtable ssp {
23*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test3
24*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %x, %x
25*9880d681SAndroid Build Coastguard Workerentry:
26*9880d681SAndroid Build Coastguard Worker  %x = load i32, i32* @y
27*9880d681SAndroid Build Coastguard Worker  %y = load atomic i32, i32* @x unordered, align 4
28*9880d681SAndroid Build Coastguard Worker  %z = load i32, i32* @y
29*9880d681SAndroid Build Coastguard Worker  %a = add i32 %x, %z
30*9880d681SAndroid Build Coastguard Worker  %b = add i32 %y, %a
31*9880d681SAndroid Build Coastguard Worker  ret i32 %b
32*9880d681SAndroid Build Coastguard Worker}
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker; GVN load to unordered load (allowed)
35*9880d681SAndroid Build Coastguard Workerdefine i32 @test5() nounwind uwtable ssp {
36*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test5
37*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %x, %x
38*9880d681SAndroid Build Coastguard Workerentry:
39*9880d681SAndroid Build Coastguard Worker  %x = load atomic i32, i32* @x unordered, align 4
40*9880d681SAndroid Build Coastguard Worker  %y = load i32, i32* @x
41*9880d681SAndroid Build Coastguard Worker  %z = add i32 %x, %y
42*9880d681SAndroid Build Coastguard Worker  ret i32 %z
43*9880d681SAndroid Build Coastguard Worker}
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker; GVN unordered load to load (unordered load must not be removed)
46*9880d681SAndroid Build Coastguard Workerdefine i32 @test6() nounwind uwtable ssp {
47*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test6
48*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* @x unordered
49*9880d681SAndroid Build Coastguard Workerentry:
50*9880d681SAndroid Build Coastguard Worker  %x = load i32, i32* @x
51*9880d681SAndroid Build Coastguard Worker  %x2 = load atomic i32, i32* @x unordered, align 4
52*9880d681SAndroid Build Coastguard Worker  %x3 = add i32 %x, %x2
53*9880d681SAndroid Build Coastguard Worker  ret i32 %x3
54*9880d681SAndroid Build Coastguard Worker}
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker; GVN across release-acquire pair (forbidden)
57*9880d681SAndroid Build Coastguard Workerdefine i32 @test7() nounwind uwtable ssp {
58*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test7
59*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %x, %y
60*9880d681SAndroid Build Coastguard Workerentry:
61*9880d681SAndroid Build Coastguard Worker  %x = load i32, i32* @y
62*9880d681SAndroid Build Coastguard Worker  store atomic i32 %x, i32* @x release, align 4
63*9880d681SAndroid Build Coastguard Worker  %w = load atomic i32, i32* @x acquire, align 4
64*9880d681SAndroid Build Coastguard Worker  %y = load i32, i32* @y
65*9880d681SAndroid Build Coastguard Worker  %z = add i32 %x, %y
66*9880d681SAndroid Build Coastguard Worker  ret i32 %z
67*9880d681SAndroid Build Coastguard Worker}
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker; GVN across monotonic store (allowed)
70*9880d681SAndroid Build Coastguard Workerdefine i32 @test9() nounwind uwtable ssp {
71*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test9
72*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %x, %x
73*9880d681SAndroid Build Coastguard Workerentry:
74*9880d681SAndroid Build Coastguard Worker  %x = load i32, i32* @y
75*9880d681SAndroid Build Coastguard Worker  store atomic i32 %x, i32* @x monotonic, align 4
76*9880d681SAndroid Build Coastguard Worker  %y = load i32, i32* @y
77*9880d681SAndroid Build Coastguard Worker  %z = add i32 %x, %y
78*9880d681SAndroid Build Coastguard Worker  ret i32 %z
79*9880d681SAndroid Build Coastguard Worker}
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker; GVN of an unordered across monotonic load (not allowed)
82*9880d681SAndroid Build Coastguard Workerdefine i32 @test10() nounwind uwtable ssp {
83*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test10
84*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 %x, %y
85*9880d681SAndroid Build Coastguard Workerentry:
86*9880d681SAndroid Build Coastguard Worker  %x = load atomic i32, i32* @y unordered, align 4
87*9880d681SAndroid Build Coastguard Worker  %clobber = load atomic i32, i32* @x monotonic, align 4
88*9880d681SAndroid Build Coastguard Worker  %y = load atomic i32, i32* @y monotonic, align 4
89*9880d681SAndroid Build Coastguard Worker  %z = add i32 %x, %y
90*9880d681SAndroid Build Coastguard Worker  ret i32 %z
91*9880d681SAndroid Build Coastguard Worker}
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Workerdefine i32 @PR22708(i1 %flag) {
94*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: PR22708
95*9880d681SAndroid Build Coastguard Workerentry:
96*9880d681SAndroid Build Coastguard Worker  br i1 %flag, label %if.then, label %if.end
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Workerif.then:
99*9880d681SAndroid Build Coastguard Worker  store i32 43, i32* @y, align 4
100*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 43, i32* @y, align 4
101*9880d681SAndroid Build Coastguard Worker  br label %if.end
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Workerif.end:
104*9880d681SAndroid Build Coastguard Worker  load atomic i32, i32* @x acquire, align 4
105*9880d681SAndroid Build Coastguard Worker  %load = load i32, i32* @y, align 4
106*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* @x acquire, align 4
107*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* @y, align 4
108*9880d681SAndroid Build Coastguard Worker  ret i32 %load
109*9880d681SAndroid Build Coastguard Worker}
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test12(
112*9880d681SAndroid Build Coastguard Worker; Can't remove a load over a ordering barrier
113*9880d681SAndroid Build Coastguard Workerdefine i32 @test12(i1 %B, i32* %P1, i32* %P2) {
114*9880d681SAndroid Build Coastguard Worker  %load0 = load i32, i32* %P1
115*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %P2 seq_cst, align 4
116*9880d681SAndroid Build Coastguard Worker  %load1 = load i32, i32* %P1
117*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %B, i32 %load0, i32 %load1
118*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
119*9880d681SAndroid Build Coastguard Worker  ; CHECK: load i32, i32* %P1
120*9880d681SAndroid Build Coastguard Worker  ; CHECK: load i32, i32* %P1
121*9880d681SAndroid Build Coastguard Worker}
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test13(
124*9880d681SAndroid Build Coastguard Worker; atomic to non-atomic forwarding is legal
125*9880d681SAndroid Build Coastguard Workerdefine i32 @test13(i32* %P1) {
126*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 seq_cst, align 4
127*9880d681SAndroid Build Coastguard Worker  %b = load i32, i32* %P1
128*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
129*9880d681SAndroid Build Coastguard Worker  ret i32 %res
130*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i32, i32* %P1
131*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 0
132*9880d681SAndroid Build Coastguard Worker}
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test13b(
135*9880d681SAndroid Build Coastguard Workerdefine i32 @test13b(i32* %P1) {
136*9880d681SAndroid Build Coastguard Worker  store  atomic i32 0, i32* %P1 unordered, align 4
137*9880d681SAndroid Build Coastguard Worker  %b = load i32, i32* %P1
138*9880d681SAndroid Build Coastguard Worker  ret i32 %b
139*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 0
140*9880d681SAndroid Build Coastguard Worker}
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test14(
143*9880d681SAndroid Build Coastguard Worker; atomic to unordered atomic forwarding is legal
144*9880d681SAndroid Build Coastguard Workerdefine i32 @test14(i32* %P1) {
145*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 seq_cst, align 4
146*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 unordered, align 4
147*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
148*9880d681SAndroid Build Coastguard Worker  ret i32 %res
149*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i32, i32* %P1 seq_cst
150*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: ret i32 0
151*9880d681SAndroid Build Coastguard Worker}
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test15(
154*9880d681SAndroid Build Coastguard Worker; implementation restriction: can't forward to stonger
155*9880d681SAndroid Build Coastguard Worker; than unordered
156*9880d681SAndroid Build Coastguard Workerdefine i32 @test15(i32* %P1, i32* %P2) {
157*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 seq_cst, align 4
158*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 seq_cst, align 4
159*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
160*9880d681SAndroid Build Coastguard Worker  ret i32 %res
161*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i32, i32* %P1
162*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i32, i32* %P1
163*9880d681SAndroid Build Coastguard Worker}
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test16(
166*9880d681SAndroid Build Coastguard Worker; forwarding non-atomic to atomic is wrong! (However,
167*9880d681SAndroid Build Coastguard Worker; it would be legal to use the later value in place of the
168*9880d681SAndroid Build Coastguard Worker; former in this particular example.  We just don't
169*9880d681SAndroid Build Coastguard Worker; do that right now.)
170*9880d681SAndroid Build Coastguard Workerdefine i32 @test16(i32* %P1, i32* %P2) {
171*9880d681SAndroid Build Coastguard Worker  %a = load i32, i32* %P1, align 4
172*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 unordered, align 4
173*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
174*9880d681SAndroid Build Coastguard Worker  ret i32 %res
175*9880d681SAndroid Build Coastguard Worker  ; CHECK: load i32, i32* %P1
176*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i32, i32* %P1
177*9880d681SAndroid Build Coastguard Worker}
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test16b(
180*9880d681SAndroid Build Coastguard Workerdefine i32 @test16b(i32* %P1) {
181*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1
182*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 unordered, align 4
183*9880d681SAndroid Build Coastguard Worker  ret i32 %b
184*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i32, i32* %P1
185*9880d681SAndroid Build Coastguard Worker}
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Worker; Can't DSE across a full fence
188*9880d681SAndroid Build Coastguard Workerdefine void @fence_seq_cst_store(i32* %P1, i32* %P2) {
189*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fence_seq_cst_store(
190*9880d681SAndroid Build Coastguard Worker; CHECK: store
191*9880d681SAndroid Build Coastguard Worker; CHECK: store atomic
192*9880d681SAndroid Build Coastguard Worker; CHECK: store
193*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
194*9880d681SAndroid Build Coastguard Worker  store atomic i32 0, i32* %P2 seq_cst, align 4
195*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
196*9880d681SAndroid Build Coastguard Worker  ret void
197*9880d681SAndroid Build Coastguard Worker}
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Worker; Can't DSE across a full fence
200*9880d681SAndroid Build Coastguard Workerdefine void @fence_seq_cst(i32* %P1, i32* %P2) {
201*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fence_seq_cst(
202*9880d681SAndroid Build Coastguard Worker; CHECK: store
203*9880d681SAndroid Build Coastguard Worker; CHECK: fence seq_cst
204*9880d681SAndroid Build Coastguard Worker; CHECK: store
205*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
206*9880d681SAndroid Build Coastguard Worker  fence seq_cst
207*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
208*9880d681SAndroid Build Coastguard Worker  ret void
209*9880d681SAndroid Build Coastguard Worker}
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Worker; Can't DSE across a full singlethread fence
212*9880d681SAndroid Build Coastguard Workerdefine void @fence_seq_cst_st(i32* %P1, i32* %P2) {
213*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fence_seq_cst_st(
214*9880d681SAndroid Build Coastguard Worker; CHECK: store
215*9880d681SAndroid Build Coastguard Worker; CHECK: fence singlethread seq_cst
216*9880d681SAndroid Build Coastguard Worker; CHECK: store
217*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
218*9880d681SAndroid Build Coastguard Worker  fence singlethread seq_cst
219*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
220*9880d681SAndroid Build Coastguard Worker  ret void
221*9880d681SAndroid Build Coastguard Worker}
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Worker; Can't DSE across a full fence
224*9880d681SAndroid Build Coastguard Workerdefine void @fence_asm_sideeffect(i32* %P1, i32* %P2) {
225*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fence_asm_sideeffect(
226*9880d681SAndroid Build Coastguard Worker; CHECK: store
227*9880d681SAndroid Build Coastguard Worker; CHECK: call void asm sideeffect
228*9880d681SAndroid Build Coastguard Worker; CHECK: store
229*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
230*9880d681SAndroid Build Coastguard Worker  call void asm sideeffect "", ""()
231*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
232*9880d681SAndroid Build Coastguard Worker  ret void
233*9880d681SAndroid Build Coastguard Worker}
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Worker; Can't DSE across a full fence
236*9880d681SAndroid Build Coastguard Workerdefine void @fence_asm_memory(i32* %P1, i32* %P2) {
237*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fence_asm_memory(
238*9880d681SAndroid Build Coastguard Worker; CHECK: store
239*9880d681SAndroid Build Coastguard Worker; CHECK: call void asm
240*9880d681SAndroid Build Coastguard Worker; CHECK: store
241*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
242*9880d681SAndroid Build Coastguard Worker  call void asm "", "~{memory}"()
243*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
244*9880d681SAndroid Build Coastguard Worker  ret void
245*9880d681SAndroid Build Coastguard Worker}
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Worker; Can't remove a volatile load
248*9880d681SAndroid Build Coastguard Workerdefine i32 @volatile_load(i32* %P1, i32* %P2) {
249*9880d681SAndroid Build Coastguard Worker  %a = load i32, i32* %P1, align 4
250*9880d681SAndroid Build Coastguard Worker  %b = load volatile i32, i32* %P1, align 4
251*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
252*9880d681SAndroid Build Coastguard Worker  ret i32 %res
253*9880d681SAndroid Build Coastguard Worker  ; CHECK-LABEL: @volatile_load(
254*9880d681SAndroid Build Coastguard Worker  ; CHECK: load i32, i32* %P1
255*9880d681SAndroid Build Coastguard Worker  ; CHECK: load volatile i32, i32* %P1
256*9880d681SAndroid Build Coastguard Worker}
257*9880d681SAndroid Build Coastguard Worker
258*9880d681SAndroid Build Coastguard Worker; Can't remove redundant volatile loads
259*9880d681SAndroid Build Coastguard Workerdefine i32 @redundant_volatile_load(i32* %P1, i32* %P2) {
260*9880d681SAndroid Build Coastguard Worker  %a = load volatile i32, i32* %P1, align 4
261*9880d681SAndroid Build Coastguard Worker  %b = load volatile i32, i32* %P1, align 4
262*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
263*9880d681SAndroid Build Coastguard Worker  ret i32 %res
264*9880d681SAndroid Build Coastguard Worker  ; CHECK-LABEL: @redundant_volatile_load(
265*9880d681SAndroid Build Coastguard Worker  ; CHECK: load volatile i32, i32* %P1
266*9880d681SAndroid Build Coastguard Worker  ; CHECK: load volatile i32, i32* %P1
267*9880d681SAndroid Build Coastguard Worker  ; CHECK: sub
268*9880d681SAndroid Build Coastguard Worker}
269*9880d681SAndroid Build Coastguard Worker
270*9880d681SAndroid Build Coastguard Worker; Can't DSE a volatile store
271*9880d681SAndroid Build Coastguard Workerdefine void @volatile_store(i32* %P1, i32* %P2) {
272*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @volatile_store(
273*9880d681SAndroid Build Coastguard Worker; CHECK: store volatile
274*9880d681SAndroid Build Coastguard Worker; CHECK: store
275*9880d681SAndroid Build Coastguard Worker  store volatile i32 0, i32* %P1, align 4
276*9880d681SAndroid Build Coastguard Worker  store i32 3, i32* %P1, align 4
277*9880d681SAndroid Build Coastguard Worker  ret void
278*9880d681SAndroid Build Coastguard Worker}
279*9880d681SAndroid Build Coastguard Worker
280*9880d681SAndroid Build Coastguard Worker; Can't DSE a redundant volatile store
281*9880d681SAndroid Build Coastguard Workerdefine void @redundant_volatile_store(i32* %P1, i32* %P2) {
282*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @redundant_volatile_store(
283*9880d681SAndroid Build Coastguard Worker; CHECK: store volatile
284*9880d681SAndroid Build Coastguard Worker; CHECK: store volatile
285*9880d681SAndroid Build Coastguard Worker  store volatile i32 0, i32* %P1, align 4
286*9880d681SAndroid Build Coastguard Worker  store volatile i32 0, i32* %P1, align 4
287*9880d681SAndroid Build Coastguard Worker  ret void
288*9880d681SAndroid Build Coastguard Worker}
289*9880d681SAndroid Build Coastguard Worker
290*9880d681SAndroid Build Coastguard Worker; Can value forward from volatiles
291*9880d681SAndroid Build Coastguard Workerdefine i32 @test20(i32* %P1, i32* %P2) {
292*9880d681SAndroid Build Coastguard Worker  %a = load volatile i32, i32* %P1, align 4
293*9880d681SAndroid Build Coastguard Worker  %b = load i32, i32* %P1, align 4
294*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
295*9880d681SAndroid Build Coastguard Worker  ret i32 %res
296*9880d681SAndroid Build Coastguard Worker  ; CHECK-LABEL: @test20(
297*9880d681SAndroid Build Coastguard Worker  ; CHECK: load volatile i32, i32* %P1
298*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 0
299*9880d681SAndroid Build Coastguard Worker}
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker; We're currently conservative about widening
302*9880d681SAndroid Build Coastguard Workerdefine i64 @widen1(i32* %P1) {
303*9880d681SAndroid Build Coastguard Worker  ; CHECK-LABEL: @widen1(
304*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i32, i32* %P1
305*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i64, i64* %p2
306*9880d681SAndroid Build Coastguard Worker  %p2 = bitcast i32* %P1 to i64*
307*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 unordered, align 4
308*9880d681SAndroid Build Coastguard Worker  %b = load atomic i64, i64* %p2 unordered, align 4
309*9880d681SAndroid Build Coastguard Worker  %a64 = sext i32 %a to i64
310*9880d681SAndroid Build Coastguard Worker  %res = sub i64 %a64, %b
311*9880d681SAndroid Build Coastguard Worker  ret i64 %res
312*9880d681SAndroid Build Coastguard Worker}
313*9880d681SAndroid Build Coastguard Worker
314*9880d681SAndroid Build Coastguard Worker; narrowing does work
315*9880d681SAndroid Build Coastguard Workerdefine i64 @narrow(i32* %P1) {
316*9880d681SAndroid Build Coastguard Worker  ; CHECK-LABEL: @narrow(
317*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i64, i64* %p2
318*9880d681SAndroid Build Coastguard Worker  ; CHECK-NOT: load atomic i32, i32* %P1
319*9880d681SAndroid Build Coastguard Worker  %p2 = bitcast i32* %P1 to i64*
320*9880d681SAndroid Build Coastguard Worker  %a64 = load atomic i64, i64* %p2 unordered, align 4
321*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 unordered, align 4
322*9880d681SAndroid Build Coastguard Worker  %b64 = sext i32 %b to i64
323*9880d681SAndroid Build Coastguard Worker  %res = sub i64 %a64, %b64
324*9880d681SAndroid Build Coastguard Worker  ret i64 %res
325*9880d681SAndroid Build Coastguard Worker}
326*9880d681SAndroid Build Coastguard Worker
327*9880d681SAndroid Build Coastguard Worker; Missed optimization, we don't yet optimize ordered loads
328*9880d681SAndroid Build Coastguard Workerdefine i64 @narrow2(i32* %P1) {
329*9880d681SAndroid Build Coastguard Worker  ; CHECK-LABEL: @narrow2(
330*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i64, i64* %p2
331*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i32, i32* %P1
332*9880d681SAndroid Build Coastguard Worker  %p2 = bitcast i32* %P1 to i64*
333*9880d681SAndroid Build Coastguard Worker  %a64 = load atomic i64, i64* %p2 acquire, align 4
334*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 acquire, align 4
335*9880d681SAndroid Build Coastguard Worker  %b64 = sext i32 %b to i64
336*9880d681SAndroid Build Coastguard Worker  %res = sub i64 %a64, %b64
337*9880d681SAndroid Build Coastguard Worker  ret i64 %res
338*9880d681SAndroid Build Coastguard Worker}
339*9880d681SAndroid Build Coastguard Worker
340*9880d681SAndroid Build Coastguard Worker; Note: The cross block FRE testing is deliberately light.  All of the tricky
341*9880d681SAndroid Build Coastguard Worker; bits of legality are shared code with the block-local FRE above.  These
342*9880d681SAndroid Build Coastguard Worker; are here only to show that we haven't obviously broken anything.
343*9880d681SAndroid Build Coastguard Worker
344*9880d681SAndroid Build Coastguard Worker; unordered atomic to unordered atomic
345*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_fre(i32* %P1) {
346*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_fre(
347*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1
348*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0
349*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0
350*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 unordered, align 4
351*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 0
352*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %early, label %next
353*9880d681SAndroid Build Coastguard Workerearly:
354*9880d681SAndroid Build Coastguard Worker  ret i32 %a
355*9880d681SAndroid Build Coastguard Workernext:
356*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 unordered, align 4
357*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
358*9880d681SAndroid Build Coastguard Worker  ret i32 %res
359*9880d681SAndroid Build Coastguard Worker}
360*9880d681SAndroid Build Coastguard Worker
361*9880d681SAndroid Build Coastguard Worker; unordered atomic to non-atomic
362*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_fre2(i32* %P1) {
363*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_fre2(
364*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1
365*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0
366*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0
367*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 unordered, align 4
368*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 0
369*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %early, label %next
370*9880d681SAndroid Build Coastguard Workerearly:
371*9880d681SAndroid Build Coastguard Worker  ret i32 %a
372*9880d681SAndroid Build Coastguard Workernext:
373*9880d681SAndroid Build Coastguard Worker  %b = load i32, i32* %P1
374*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
375*9880d681SAndroid Build Coastguard Worker  ret i32 %res
376*9880d681SAndroid Build Coastguard Worker}
377*9880d681SAndroid Build Coastguard Worker
378*9880d681SAndroid Build Coastguard Worker; Can't forward ordered atomics.
379*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_fre3(i32* %P1) {
380*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_fre3(
381*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 acquire
382*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0
383*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 acquire
384*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %res
385*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 acquire, align 4
386*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 0
387*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %early, label %next
388*9880d681SAndroid Build Coastguard Workerearly:
389*9880d681SAndroid Build Coastguard Worker  ret i32 %a
390*9880d681SAndroid Build Coastguard Workernext:
391*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 acquire, align 4
392*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
393*9880d681SAndroid Build Coastguard Worker  ret i32 %res
394*9880d681SAndroid Build Coastguard Worker}
395*9880d681SAndroid Build Coastguard Worker
396*9880d681SAndroid Build Coastguard Workerdeclare void @clobber()
397*9880d681SAndroid Build Coastguard Worker
398*9880d681SAndroid Build Coastguard Worker; unordered atomic to unordered atomic
399*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_pre(i32* %P1) {
400*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_pre(
401*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 unordered
402*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 unordered
403*9880d681SAndroid Build Coastguard Worker; CHECK: %b = phi i32 [ %b.pre, %early ], [ %a, %0 ]
404*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %b
405*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 unordered, align 4
406*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 0
407*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %early, label %next
408*9880d681SAndroid Build Coastguard Workerearly:
409*9880d681SAndroid Build Coastguard Worker  call void @clobber()
410*9880d681SAndroid Build Coastguard Worker  br label %next
411*9880d681SAndroid Build Coastguard Workernext:
412*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 unordered, align 4
413*9880d681SAndroid Build Coastguard Worker  ret i32 %b
414*9880d681SAndroid Build Coastguard Worker}
415*9880d681SAndroid Build Coastguard Worker
416*9880d681SAndroid Build Coastguard Worker; unordered atomic to non-atomic
417*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_pre2(i32* %P1) {
418*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_pre2(
419*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 unordered
420*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32* %P1
421*9880d681SAndroid Build Coastguard Worker; CHECK: %b = phi i32 [ %b.pre, %early ], [ %a, %0 ]
422*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %b
423*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 unordered, align 4
424*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 0
425*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %early, label %next
426*9880d681SAndroid Build Coastguard Workerearly:
427*9880d681SAndroid Build Coastguard Worker  call void @clobber()
428*9880d681SAndroid Build Coastguard Worker  br label %next
429*9880d681SAndroid Build Coastguard Workernext:
430*9880d681SAndroid Build Coastguard Worker  %b = load i32, i32* %P1
431*9880d681SAndroid Build Coastguard Worker  ret i32 %b
432*9880d681SAndroid Build Coastguard Worker}
433*9880d681SAndroid Build Coastguard Worker
434*9880d681SAndroid Build Coastguard Worker; non-atomic to unordered atomic - can't forward!
435*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_pre3(i32* %P1) {
436*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_pre3(
437*9880d681SAndroid Build Coastguard Worker; CHECK: %a = load i32, i32* %P1
438*9880d681SAndroid Build Coastguard Worker; CHECK: %b = load atomic i32, i32* %P1 unordered
439*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %b
440*9880d681SAndroid Build Coastguard Worker  %a = load i32, i32* %P1
441*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 0
442*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %early, label %next
443*9880d681SAndroid Build Coastguard Workerearly:
444*9880d681SAndroid Build Coastguard Worker  call void @clobber()
445*9880d681SAndroid Build Coastguard Worker  br label %next
446*9880d681SAndroid Build Coastguard Workernext:
447*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 unordered, align 4
448*9880d681SAndroid Build Coastguard Worker  ret i32 %b
449*9880d681SAndroid Build Coastguard Worker}
450*9880d681SAndroid Build Coastguard Worker
451*9880d681SAndroid Build Coastguard Worker; ordered atomic to ordered atomic - can't forward
452*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_pre4(i32* %P1) {
453*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_pre4(
454*9880d681SAndroid Build Coastguard Worker; CHECK: %a = load atomic i32, i32* %P1 seq_cst
455*9880d681SAndroid Build Coastguard Worker; CHECK: %b = load atomic i32, i32* %P1 seq_cst
456*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %b
457*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 seq_cst, align 4
458*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 0
459*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %early, label %next
460*9880d681SAndroid Build Coastguard Workerearly:
461*9880d681SAndroid Build Coastguard Worker  call void @clobber()
462*9880d681SAndroid Build Coastguard Worker  br label %next
463*9880d681SAndroid Build Coastguard Workernext:
464*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 seq_cst, align 4
465*9880d681SAndroid Build Coastguard Worker  ret i32 %b
466*9880d681SAndroid Build Coastguard Worker}
467*9880d681SAndroid Build Coastguard Worker
468*9880d681SAndroid Build Coastguard Worker; can't remove volatile on any path
469*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_pre5(i32* %P1) {
470*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_pre5(
471*9880d681SAndroid Build Coastguard Worker; CHECK: %a = load atomic i32, i32* %P1 seq_cst
472*9880d681SAndroid Build Coastguard Worker; CHECK: %b = load volatile i32, i32* %P1
473*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %b
474*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 seq_cst, align 4
475*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 0
476*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %early, label %next
477*9880d681SAndroid Build Coastguard Workerearly:
478*9880d681SAndroid Build Coastguard Worker  call void @clobber()
479*9880d681SAndroid Build Coastguard Worker  br label %next
480*9880d681SAndroid Build Coastguard Workernext:
481*9880d681SAndroid Build Coastguard Worker  %b = load volatile i32, i32* %P1
482*9880d681SAndroid Build Coastguard Worker  ret i32 %b
483*9880d681SAndroid Build Coastguard Worker}
484*9880d681SAndroid Build Coastguard Worker
485*9880d681SAndroid Build Coastguard Worker
486*9880d681SAndroid Build Coastguard Worker; ordered atomic to unordered atomic
487*9880d681SAndroid Build Coastguard Workerdefine i32 @non_local_pre6(i32* %P1) {
488*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_local_pre6(
489*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 seq_cst
490*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %P1 unordered
491*9880d681SAndroid Build Coastguard Worker; CHECK: %b = phi i32 [ %b.pre, %early ], [ %a, %0 ]
492*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 %b
493*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 seq_cst, align 4
494*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32 %a, 0
495*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %early, label %next
496*9880d681SAndroid Build Coastguard Workerearly:
497*9880d681SAndroid Build Coastguard Worker  call void @clobber()
498*9880d681SAndroid Build Coastguard Worker  br label %next
499*9880d681SAndroid Build Coastguard Workernext:
500*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 unordered, align 4
501*9880d681SAndroid Build Coastguard Worker  ret i32 %b
502*9880d681SAndroid Build Coastguard Worker}
503*9880d681SAndroid Build Coastguard Worker
504