xref: /aosp_15_r20/external/llvm/test/Transforms/EarlyCSE/atomics.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -S -early-cse | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test12(
4*9880d681SAndroid Build Coastguard Workerdefine i32 @test12(i1 %B, i32* %P1, i32* %P2) {
5*9880d681SAndroid Build Coastguard Worker  %load0 = load i32, i32* %P1
6*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %P2 seq_cst, align 4
7*9880d681SAndroid Build Coastguard Worker  %load1 = load i32, i32* %P1
8*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %B, i32 %load0, i32 %load1
9*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
10*9880d681SAndroid Build Coastguard Worker  ; CHECK: load i32, i32* %P1
11*9880d681SAndroid Build Coastguard Worker  ; CHECK: load i32, i32* %P1
12*9880d681SAndroid Build Coastguard Worker}
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test13(
15*9880d681SAndroid Build Coastguard Worker; atomic to non-atomic forwarding is legal
16*9880d681SAndroid Build Coastguard Workerdefine i32 @test13(i1 %B, i32* %P1) {
17*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 seq_cst, align 4
18*9880d681SAndroid Build Coastguard Worker  %b = load i32, i32* %P1
19*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
20*9880d681SAndroid Build Coastguard Worker  ret i32 %res
21*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i32, i32* %P1
22*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 0
23*9880d681SAndroid Build Coastguard Worker}
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test14(
26*9880d681SAndroid Build Coastguard Worker; atomic to unordered atomic forwarding is legal
27*9880d681SAndroid Build Coastguard Workerdefine i32 @test14(i1 %B, i32* %P1) {
28*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 seq_cst, align 4
29*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 unordered, align 4
30*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
31*9880d681SAndroid Build Coastguard Worker  ret i32 %res
32*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i32, i32* %P1 seq_cst
33*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: ret i32 0
34*9880d681SAndroid Build Coastguard Worker}
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test15(
37*9880d681SAndroid Build Coastguard Worker; implementation restriction: can't forward to stonger
38*9880d681SAndroid Build Coastguard Worker; than unordered
39*9880d681SAndroid Build Coastguard Workerdefine i32 @test15(i1 %B, i32* %P1, i32* %P2) {
40*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %P1 seq_cst, align 4
41*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 seq_cst, align 4
42*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
43*9880d681SAndroid Build Coastguard Worker  ret i32 %res
44*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i32, i32* %P1
45*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i32, i32* %P1
46*9880d681SAndroid Build Coastguard Worker}
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test16(
49*9880d681SAndroid Build Coastguard Worker; forwarding non-atomic to atomic is wrong! (However,
50*9880d681SAndroid Build Coastguard Worker; it would be legal to use the later value in place of the
51*9880d681SAndroid Build Coastguard Worker; former in this particular example.  We just don't
52*9880d681SAndroid Build Coastguard Worker; do that right now.)
53*9880d681SAndroid Build Coastguard Workerdefine i32 @test16(i1 %B, i32* %P1, i32* %P2) {
54*9880d681SAndroid Build Coastguard Worker  %a = load i32, i32* %P1, align 4
55*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %P1 unordered, align 4
56*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
57*9880d681SAndroid Build Coastguard Worker  ret i32 %res
58*9880d681SAndroid Build Coastguard Worker  ; CHECK: load i32, i32* %P1
59*9880d681SAndroid Build Coastguard Worker  ; CHECK: load atomic i32, i32* %P1
60*9880d681SAndroid Build Coastguard Worker}
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker; Can't DSE across a full fence
63*9880d681SAndroid Build Coastguard Workerdefine void @fence_seq_cst_store(i1 %B, i32* %P1, i32* %P2) {
64*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fence_seq_cst_store
65*9880d681SAndroid Build Coastguard Worker; CHECK: store
66*9880d681SAndroid Build Coastguard Worker; CHECK: store atomic
67*9880d681SAndroid Build Coastguard Worker; CHECK: store
68*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
69*9880d681SAndroid Build Coastguard Worker  store atomic i32 0, i32* %P2 seq_cst, align 4
70*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
71*9880d681SAndroid Build Coastguard Worker  ret void
72*9880d681SAndroid Build Coastguard Worker}
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard Worker; Can't DSE across a full fence
75*9880d681SAndroid Build Coastguard Workerdefine void @fence_seq_cst(i1 %B, i32* %P1, i32* %P2) {
76*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fence_seq_cst
77*9880d681SAndroid Build Coastguard Worker; CHECK: store
78*9880d681SAndroid Build Coastguard Worker; CHECK: fence seq_cst
79*9880d681SAndroid Build Coastguard Worker; CHECK: store
80*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
81*9880d681SAndroid Build Coastguard Worker  fence seq_cst
82*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
83*9880d681SAndroid Build Coastguard Worker  ret void
84*9880d681SAndroid Build Coastguard Worker}
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Worker; Can't DSE across a full fence
87*9880d681SAndroid Build Coastguard Workerdefine void @fence_asm_sideeffect(i1 %B, i32* %P1, i32* %P2) {
88*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fence_asm_sideeffect
89*9880d681SAndroid Build Coastguard Worker; CHECK: store
90*9880d681SAndroid Build Coastguard Worker; CHECK: call void asm sideeffect
91*9880d681SAndroid Build Coastguard Worker; CHECK: store
92*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
93*9880d681SAndroid Build Coastguard Worker  call void asm sideeffect "", ""()
94*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
95*9880d681SAndroid Build Coastguard Worker  ret void
96*9880d681SAndroid Build Coastguard Worker}
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker; Can't DSE across a full fence
99*9880d681SAndroid Build Coastguard Workerdefine void @fence_asm_memory(i1 %B, i32* %P1, i32* %P2) {
100*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fence_asm_memory
101*9880d681SAndroid Build Coastguard Worker; CHECK: store
102*9880d681SAndroid Build Coastguard Worker; CHECK: call void asm
103*9880d681SAndroid Build Coastguard Worker; CHECK: store
104*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
105*9880d681SAndroid Build Coastguard Worker  call void asm "", "~{memory}"()
106*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
107*9880d681SAndroid Build Coastguard Worker  ret void
108*9880d681SAndroid Build Coastguard Worker}
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Worker; Can't remove a volatile load
111*9880d681SAndroid Build Coastguard Workerdefine i32 @volatile_load(i1 %B, i32* %P1, i32* %P2) {
112*9880d681SAndroid Build Coastguard Worker  %a = load i32, i32* %P1, align 4
113*9880d681SAndroid Build Coastguard Worker  %b = load volatile i32, i32* %P1, align 4
114*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
115*9880d681SAndroid Build Coastguard Worker  ret i32 %res
116*9880d681SAndroid Build Coastguard Worker  ; CHECK-LABEL: @volatile_load
117*9880d681SAndroid Build Coastguard Worker  ; CHECK: load i32, i32* %P1
118*9880d681SAndroid Build Coastguard Worker  ; CHECK: load volatile i32, i32* %P1
119*9880d681SAndroid Build Coastguard Worker}
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Worker; Can't remove redundant volatile loads
122*9880d681SAndroid Build Coastguard Workerdefine i32 @redundant_volatile_load(i1 %B, i32* %P1, i32* %P2) {
123*9880d681SAndroid Build Coastguard Worker  %a = load volatile i32, i32* %P1, align 4
124*9880d681SAndroid Build Coastguard Worker  %b = load volatile i32, i32* %P1, align 4
125*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
126*9880d681SAndroid Build Coastguard Worker  ret i32 %res
127*9880d681SAndroid Build Coastguard Worker  ; CHECK-LABEL: @redundant_volatile_load
128*9880d681SAndroid Build Coastguard Worker  ; CHECK: load volatile i32, i32* %P1
129*9880d681SAndroid Build Coastguard Worker  ; CHECK: load volatile i32, i32* %P1
130*9880d681SAndroid Build Coastguard Worker  ; CHECK: sub
131*9880d681SAndroid Build Coastguard Worker}
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker; Can't DSE a volatile store
134*9880d681SAndroid Build Coastguard Workerdefine void @volatile_store(i1 %B, i32* %P1, i32* %P2) {
135*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @volatile_store
136*9880d681SAndroid Build Coastguard Worker; CHECK: store volatile
137*9880d681SAndroid Build Coastguard Worker; CHECK: store
138*9880d681SAndroid Build Coastguard Worker  store volatile i32 0, i32* %P1, align 4
139*9880d681SAndroid Build Coastguard Worker  store i32 3, i32* %P1, align 4
140*9880d681SAndroid Build Coastguard Worker  ret void
141*9880d681SAndroid Build Coastguard Worker}
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker; Can't DSE a redundant volatile store
144*9880d681SAndroid Build Coastguard Workerdefine void @redundant_volatile_store(i1 %B, i32* %P1, i32* %P2) {
145*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @redundant_volatile_store
146*9880d681SAndroid Build Coastguard Worker; CHECK: store volatile
147*9880d681SAndroid Build Coastguard Worker; CHECK: store volatile
148*9880d681SAndroid Build Coastguard Worker  store volatile i32 0, i32* %P1, align 4
149*9880d681SAndroid Build Coastguard Worker  store volatile i32 0, i32* %P1, align 4
150*9880d681SAndroid Build Coastguard Worker  ret void
151*9880d681SAndroid Build Coastguard Worker}
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker; Can value forward from volatiles
154*9880d681SAndroid Build Coastguard Workerdefine i32 @test20(i1 %B, i32* %P1, i32* %P2) {
155*9880d681SAndroid Build Coastguard Worker  %a = load volatile i32, i32* %P1, align 4
156*9880d681SAndroid Build Coastguard Worker  %b = load i32, i32* %P1, align 4
157*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
158*9880d681SAndroid Build Coastguard Worker  ret i32 %res
159*9880d681SAndroid Build Coastguard Worker  ; CHECK-LABEL: @test20
160*9880d681SAndroid Build Coastguard Worker  ; CHECK: load volatile i32, i32* %P1
161*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 0
162*9880d681SAndroid Build Coastguard Worker}
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker; Can DSE a non-volatile store in favor of a volatile one
165*9880d681SAndroid Build Coastguard Worker; currently a missed optimization
166*9880d681SAndroid Build Coastguard Workerdefine void @test21(i1 %B, i32* %P1, i32* %P2) {
167*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test21
168*9880d681SAndroid Build Coastguard Worker; CHECK: store
169*9880d681SAndroid Build Coastguard Worker; CHECK: store volatile
170*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
171*9880d681SAndroid Build Coastguard Worker  store volatile i32 3, i32* %P1, align 4
172*9880d681SAndroid Build Coastguard Worker  ret void
173*9880d681SAndroid Build Coastguard Worker}
174*9880d681SAndroid Build Coastguard Worker
175*9880d681SAndroid Build Coastguard Worker; Can DSE a normal store in favor of a unordered one
176*9880d681SAndroid Build Coastguard Workerdefine void @test22(i1 %B, i32* %P1, i32* %P2) {
177*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test22
178*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store atomic
179*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
180*9880d681SAndroid Build Coastguard Worker  store atomic i32 3, i32* %P1 unordered, align 4
181*9880d681SAndroid Build Coastguard Worker  ret void
182*9880d681SAndroid Build Coastguard Worker}
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Worker; Can also DSE a unordered store in favor of a normal one
185*9880d681SAndroid Build Coastguard Workerdefine void @test23(i1 %B, i32* %P1, i32* %P2) {
186*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test23
187*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store i32 0
188*9880d681SAndroid Build Coastguard Worker  store atomic i32 3, i32* %P1 unordered, align 4
189*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
190*9880d681SAndroid Build Coastguard Worker  ret void
191*9880d681SAndroid Build Coastguard Worker}
192*9880d681SAndroid Build Coastguard Worker
193*9880d681SAndroid Build Coastguard Worker; As an implementation limitation, can't remove ordered stores
194*9880d681SAndroid Build Coastguard Worker; Note that we could remove the earlier store if we could
195*9880d681SAndroid Build Coastguard Worker; represent the required ordering.
196*9880d681SAndroid Build Coastguard Workerdefine void @test24(i1 %B, i32* %P1, i32* %P2) {
197*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test24
198*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store atomic
199*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store i32 0
200*9880d681SAndroid Build Coastguard Worker  store atomic i32 3, i32* %P1 release, align 4
201*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %P1, align 4
202*9880d681SAndroid Build Coastguard Worker  ret void
203*9880d681SAndroid Build Coastguard Worker}
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Worker; Can't remove volatile stores - each is independently observable and
206*9880d681SAndroid Build Coastguard Worker; the count of such stores is an observable program side effect.
207*9880d681SAndroid Build Coastguard Workerdefine void @test25(i1 %B, i32* %P1, i32* %P2) {
208*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test25
209*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store volatile
210*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store volatile
211*9880d681SAndroid Build Coastguard Worker  store volatile i32 3, i32* %P1, align 4
212*9880d681SAndroid Build Coastguard Worker  store volatile i32 0, i32* %P1, align 4
213*9880d681SAndroid Build Coastguard Worker  ret void
214*9880d681SAndroid Build Coastguard Worker}
215*9880d681SAndroid Build Coastguard Worker
216*9880d681SAndroid Build Coastguard Worker; Can DSE a unordered store in favor of a unordered one
217*9880d681SAndroid Build Coastguard Workerdefine void @test26(i1 %B, i32* %P1, i32* %P2) {
218*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test26
219*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store atomic i32 3, i32* %P1 unordered, align 4
220*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
221*9880d681SAndroid Build Coastguard Worker  store atomic i32 0, i32* %P1 unordered, align 4
222*9880d681SAndroid Build Coastguard Worker  store atomic i32 3, i32* %P1 unordered, align 4
223*9880d681SAndroid Build Coastguard Worker  ret void
224*9880d681SAndroid Build Coastguard Worker}
225*9880d681SAndroid Build Coastguard Worker
226*9880d681SAndroid Build Coastguard Worker; Can DSE a unordered store in favor of a ordered one,
227*9880d681SAndroid Build Coastguard Worker; but current don't due to implementation limits
228*9880d681SAndroid Build Coastguard Workerdefine void @test27(i1 %B, i32* %P1, i32* %P2) {
229*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test27
230*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store atomic i32 0, i32* %P1 unordered, align 4
231*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store atomic i32 3, i32* %P1 release, align 4
232*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
233*9880d681SAndroid Build Coastguard Worker  store atomic i32 0, i32* %P1 unordered, align 4
234*9880d681SAndroid Build Coastguard Worker  store atomic i32 3, i32* %P1 release, align 4
235*9880d681SAndroid Build Coastguard Worker  ret void
236*9880d681SAndroid Build Coastguard Worker}
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Worker; Can DSE an unordered atomic store in favor of an
239*9880d681SAndroid Build Coastguard Worker; ordered one, but current don't due to implementation limits
240*9880d681SAndroid Build Coastguard Workerdefine void @test28(i1 %B, i32* %P1, i32* %P2) {
241*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test28
242*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store atomic i32 0, i32* %P1 unordered, align 4
243*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store atomic i32 3, i32* %P1 release, align 4
244*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
245*9880d681SAndroid Build Coastguard Worker  store atomic i32 0, i32* %P1 unordered, align 4
246*9880d681SAndroid Build Coastguard Worker  store atomic i32 3, i32* %P1 release, align 4
247*9880d681SAndroid Build Coastguard Worker  ret void
248*9880d681SAndroid Build Coastguard Worker}
249*9880d681SAndroid Build Coastguard Worker
250*9880d681SAndroid Build Coastguard Worker; As an implementation limitation, can't remove ordered stores
251*9880d681SAndroid Build Coastguard Worker; see also: @test24
252*9880d681SAndroid Build Coastguard Workerdefine void @test29(i1 %B, i32* %P1, i32* %P2) {
253*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test29
254*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store atomic
255*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store atomic
256*9880d681SAndroid Build Coastguard Worker  store atomic i32 3, i32* %P1 release, align 4
257*9880d681SAndroid Build Coastguard Worker  store atomic i32 0, i32* %P1 unordered, align 4
258*9880d681SAndroid Build Coastguard Worker  ret void
259*9880d681SAndroid Build Coastguard Worker}
260