xref: /aosp_15_r20/external/llvm/test/Transforms/EarlyCSE/basic.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -S -early-cse | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -S -passes=early-cse | FileCheck %s
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.assume(i1) nounwind
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1(
7*9880d681SAndroid Build Coastguard Workerdefine void @test1(i8 %V, i32 *%P) {
8*9880d681SAndroid Build Coastguard Worker  %A = bitcast i64 42 to double  ;; dead
9*9880d681SAndroid Build Coastguard Worker  %B = add i32 4, 19             ;; constant folds
10*9880d681SAndroid Build Coastguard Worker  store i32 %B, i32* %P
11*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: store i32 23, i32* %P
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Worker  %C = zext i8 %V to i32
14*9880d681SAndroid Build Coastguard Worker  %D = zext i8 %V to i32  ;; CSE
15*9880d681SAndroid Build Coastguard Worker  store volatile i32 %C, i32* %P
16*9880d681SAndroid Build Coastguard Worker  store volatile i32 %D, i32* %P
17*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: %C = zext i8 %V to i32
18*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: store volatile i32 %C
19*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: store volatile i32 %C
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker  %E = add i32 %C, %C
22*9880d681SAndroid Build Coastguard Worker  %F = add i32 %C, %C
23*9880d681SAndroid Build Coastguard Worker  store volatile i32 %E, i32* %P
24*9880d681SAndroid Build Coastguard Worker  store volatile i32 %F, i32* %P
25*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: %E = add i32 %C, %C
26*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: store volatile i32 %E
27*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: store volatile i32 %E
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker  %G = add nuw i32 %C, %C
30*9880d681SAndroid Build Coastguard Worker  store volatile i32 %G, i32* %P
31*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: store volatile i32 %E
32*9880d681SAndroid Build Coastguard Worker  ret void
33*9880d681SAndroid Build Coastguard Worker}
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker;; Simple load value numbering.
37*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2(
38*9880d681SAndroid Build Coastguard Workerdefine i32 @test2(i32 *%P) {
39*9880d681SAndroid Build Coastguard Worker  %V1 = load i32, i32* %P
40*9880d681SAndroid Build Coastguard Worker  %V2 = load i32, i32* %P
41*9880d681SAndroid Build Coastguard Worker  %Diff = sub i32 %V1, %V2
42*9880d681SAndroid Build Coastguard Worker  ret i32 %Diff
43*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 0
44*9880d681SAndroid Build Coastguard Worker}
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2a(
47*9880d681SAndroid Build Coastguard Workerdefine i32 @test2a(i32 *%P, i1 %b) {
48*9880d681SAndroid Build Coastguard Worker  %V1 = load i32, i32* %P
49*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %b)
50*9880d681SAndroid Build Coastguard Worker  %V2 = load i32, i32* %P
51*9880d681SAndroid Build Coastguard Worker  %Diff = sub i32 %V1, %V2
52*9880d681SAndroid Build Coastguard Worker  ret i32 %Diff
53*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 0
54*9880d681SAndroid Build Coastguard Worker}
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker;; Cross block load value numbering.
57*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3(
58*9880d681SAndroid Build Coastguard Workerdefine i32 @test3(i32 *%P, i1 %Cond) {
59*9880d681SAndroid Build Coastguard Worker  %V1 = load i32, i32* %P
60*9880d681SAndroid Build Coastguard Worker  br i1 %Cond, label %T, label %F
61*9880d681SAndroid Build Coastguard WorkerT:
62*9880d681SAndroid Build Coastguard Worker  store i32 4, i32* %P
63*9880d681SAndroid Build Coastguard Worker  ret i32 42
64*9880d681SAndroid Build Coastguard WorkerF:
65*9880d681SAndroid Build Coastguard Worker  %V2 = load i32, i32* %P
66*9880d681SAndroid Build Coastguard Worker  %Diff = sub i32 %V1, %V2
67*9880d681SAndroid Build Coastguard Worker  ret i32 %Diff
68*9880d681SAndroid Build Coastguard Worker  ; CHECK: F:
69*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 0
70*9880d681SAndroid Build Coastguard Worker}
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3a(
73*9880d681SAndroid Build Coastguard Workerdefine i32 @test3a(i32 *%P, i1 %Cond, i1 %b) {
74*9880d681SAndroid Build Coastguard Worker  %V1 = load i32, i32* %P
75*9880d681SAndroid Build Coastguard Worker  br i1 %Cond, label %T, label %F
76*9880d681SAndroid Build Coastguard WorkerT:
77*9880d681SAndroid Build Coastguard Worker  store i32 4, i32* %P
78*9880d681SAndroid Build Coastguard Worker  ret i32 42
79*9880d681SAndroid Build Coastguard WorkerF:
80*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %b)
81*9880d681SAndroid Build Coastguard Worker  %V2 = load i32, i32* %P
82*9880d681SAndroid Build Coastguard Worker  %Diff = sub i32 %V1, %V2
83*9880d681SAndroid Build Coastguard Worker  ret i32 %Diff
84*9880d681SAndroid Build Coastguard Worker  ; CHECK: F:
85*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 0
86*9880d681SAndroid Build Coastguard Worker}
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker;; Cross block load value numbering stops when stores happen.
89*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4(
90*9880d681SAndroid Build Coastguard Workerdefine i32 @test4(i32 *%P, i1 %Cond) {
91*9880d681SAndroid Build Coastguard Worker  %V1 = load i32, i32* %P
92*9880d681SAndroid Build Coastguard Worker  br i1 %Cond, label %T, label %F
93*9880d681SAndroid Build Coastguard WorkerT:
94*9880d681SAndroid Build Coastguard Worker  ret i32 42
95*9880d681SAndroid Build Coastguard WorkerF:
96*9880d681SAndroid Build Coastguard Worker  ; Clobbers V1
97*9880d681SAndroid Build Coastguard Worker  store i32 42, i32* %P
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker  %V2 = load i32, i32* %P
100*9880d681SAndroid Build Coastguard Worker  %Diff = sub i32 %V1, %V2
101*9880d681SAndroid Build Coastguard Worker  ret i32 %Diff
102*9880d681SAndroid Build Coastguard Worker  ; CHECK: F:
103*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 %Diff
104*9880d681SAndroid Build Coastguard Worker}
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Workerdeclare i32 @func(i32 *%P) readonly
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker;; Simple call CSE'ing.
109*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5(
110*9880d681SAndroid Build Coastguard Workerdefine i32 @test5(i32 *%P) {
111*9880d681SAndroid Build Coastguard Worker  %V1 = call i32 @func(i32* %P)
112*9880d681SAndroid Build Coastguard Worker  %V2 = call i32 @func(i32* %P)
113*9880d681SAndroid Build Coastguard Worker  %Diff = sub i32 %V1, %V2
114*9880d681SAndroid Build Coastguard Worker  ret i32 %Diff
115*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 0
116*9880d681SAndroid Build Coastguard Worker}
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker;; Trivial Store->load forwarding
119*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6(
120*9880d681SAndroid Build Coastguard Workerdefine i32 @test6(i32 *%P) {
121*9880d681SAndroid Build Coastguard Worker  store i32 42, i32* %P
122*9880d681SAndroid Build Coastguard Worker  %V1 = load i32, i32* %P
123*9880d681SAndroid Build Coastguard Worker  ret i32 %V1
124*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 42
125*9880d681SAndroid Build Coastguard Worker}
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6a(
128*9880d681SAndroid Build Coastguard Workerdefine i32 @test6a(i32 *%P, i1 %b) {
129*9880d681SAndroid Build Coastguard Worker  store i32 42, i32* %P
130*9880d681SAndroid Build Coastguard Worker  tail call void @llvm.assume(i1 %b)
131*9880d681SAndroid Build Coastguard Worker  %V1 = load i32, i32* %P
132*9880d681SAndroid Build Coastguard Worker  ret i32 %V1
133*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 42
134*9880d681SAndroid Build Coastguard Worker}
135*9880d681SAndroid Build Coastguard Worker
136*9880d681SAndroid Build Coastguard Worker;; Trivial dead store elimination.
137*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test7(
138*9880d681SAndroid Build Coastguard Workerdefine void @test7(i32 *%P) {
139*9880d681SAndroid Build Coastguard Worker  store i32 42, i32* %P
140*9880d681SAndroid Build Coastguard Worker  store i32 45, i32* %P
141*9880d681SAndroid Build Coastguard Worker  ret void
142*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: store i32 45
143*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: ret void
144*9880d681SAndroid Build Coastguard Worker}
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker;; Readnone functions aren't invalidated by stores.
147*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test8(
148*9880d681SAndroid Build Coastguard Workerdefine i32 @test8(i32 *%P) {
149*9880d681SAndroid Build Coastguard Worker  %V1 = call i32 @func(i32* %P) readnone
150*9880d681SAndroid Build Coastguard Worker  store i32 4, i32* %P
151*9880d681SAndroid Build Coastguard Worker  %V2 = call i32 @func(i32* %P) readnone
152*9880d681SAndroid Build Coastguard Worker  %Diff = sub i32 %V1, %V2
153*9880d681SAndroid Build Coastguard Worker  ret i32 %Diff
154*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 0
155*9880d681SAndroid Build Coastguard Worker}
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Worker;; Trivial DSE can't be performed across a readonly call.  The call
158*9880d681SAndroid Build Coastguard Worker;; can observe the earlier write.
159*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test9(
160*9880d681SAndroid Build Coastguard Workerdefine i32 @test9(i32 *%P) {
161*9880d681SAndroid Build Coastguard Worker  store i32 4, i32* %P
162*9880d681SAndroid Build Coastguard Worker  %V1 = call i32 @func(i32* %P) readonly
163*9880d681SAndroid Build Coastguard Worker  store i32 5, i32* %P
164*9880d681SAndroid Build Coastguard Worker  ret i32 %V1
165*9880d681SAndroid Build Coastguard Worker  ; CHECK: store i32 4, i32* %P
166*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: %V1 = call i32 @func(i32* %P)
167*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: store i32 5, i32* %P
168*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: ret i32 %V1
169*9880d681SAndroid Build Coastguard Worker}
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker;; Trivial DSE can be performed across a readnone call.
172*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test10
173*9880d681SAndroid Build Coastguard Workerdefine i32 @test10(i32 *%P) {
174*9880d681SAndroid Build Coastguard Worker  store i32 4, i32* %P
175*9880d681SAndroid Build Coastguard Worker  %V1 = call i32 @func(i32* %P) readnone
176*9880d681SAndroid Build Coastguard Worker  store i32 5, i32* %P
177*9880d681SAndroid Build Coastguard Worker  ret i32 %V1
178*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: %V1 = call i32 @func(i32* %P)
179*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: store i32 5, i32* %P
180*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: ret i32 %V1
181*9880d681SAndroid Build Coastguard Worker}
182*9880d681SAndroid Build Coastguard Worker
183*9880d681SAndroid Build Coastguard Worker;; Trivial dead store elimination - should work for an entire series of dead stores too.
184*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test11(
185*9880d681SAndroid Build Coastguard Workerdefine void @test11(i32 *%P) {
186*9880d681SAndroid Build Coastguard Worker  store i32 42, i32* %P
187*9880d681SAndroid Build Coastguard Worker  store i32 43, i32* %P
188*9880d681SAndroid Build Coastguard Worker  store i32 44, i32* %P
189*9880d681SAndroid Build Coastguard Worker  store i32 45, i32* %P
190*9880d681SAndroid Build Coastguard Worker  ret void
191*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: store i32 45
192*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: ret void
193*9880d681SAndroid Build Coastguard Worker}
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test12(
196*9880d681SAndroid Build Coastguard Workerdefine i32 @test12(i1 %B, i32* %P1, i32* %P2) {
197*9880d681SAndroid Build Coastguard Worker  %load0 = load i32, i32* %P1
198*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %P2 seq_cst, align 4
199*9880d681SAndroid Build Coastguard Worker  %load1 = load i32, i32* %P1
200*9880d681SAndroid Build Coastguard Worker  %sel = select i1 %B, i32 %load0, i32 %load1
201*9880d681SAndroid Build Coastguard Worker  ret i32 %sel
202*9880d681SAndroid Build Coastguard Worker  ; CHECK: load i32, i32* %P1
203*9880d681SAndroid Build Coastguard Worker  ; CHECK: load i32, i32* %P1
204*9880d681SAndroid Build Coastguard Worker}
205*9880d681SAndroid Build Coastguard Worker
206*9880d681SAndroid Build Coastguard Workerdefine void @dse1(i32 *%P) {
207*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @dse1
208*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store
209*9880d681SAndroid Build Coastguard Worker  %v = load i32, i32* %P
210*9880d681SAndroid Build Coastguard Worker  store i32 %v, i32* %P
211*9880d681SAndroid Build Coastguard Worker  ret void
212*9880d681SAndroid Build Coastguard Worker}
213*9880d681SAndroid Build Coastguard Worker
214*9880d681SAndroid Build Coastguard Workerdefine void @dse2(i32 *%P) {
215*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @dse2
216*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store
217*9880d681SAndroid Build Coastguard Worker  %v = load atomic i32, i32* %P seq_cst, align 4
218*9880d681SAndroid Build Coastguard Worker  store i32 %v, i32* %P
219*9880d681SAndroid Build Coastguard Worker  ret void
220*9880d681SAndroid Build Coastguard Worker}
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Workerdefine void @dse3(i32 *%P) {
223*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @dse3
224*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store
225*9880d681SAndroid Build Coastguard Worker  %v = load atomic i32, i32* %P seq_cst, align 4
226*9880d681SAndroid Build Coastguard Worker  store atomic i32 %v, i32* %P unordered, align 4
227*9880d681SAndroid Build Coastguard Worker  ret void
228*9880d681SAndroid Build Coastguard Worker}
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Workerdefine i32 @dse4(i32 *%P, i32 *%Q) {
231*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @dse4
232*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store
233*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0
234*9880d681SAndroid Build Coastguard Worker  %a = load i32, i32* %Q
235*9880d681SAndroid Build Coastguard Worker  %v = load atomic i32, i32* %P unordered, align 4
236*9880d681SAndroid Build Coastguard Worker  store atomic i32 %v, i32* %P unordered, align 4
237*9880d681SAndroid Build Coastguard Worker  %b = load i32, i32* %Q
238*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
239*9880d681SAndroid Build Coastguard Worker  ret i32 %res
240*9880d681SAndroid Build Coastguard Worker}
241*9880d681SAndroid Build Coastguard Worker
242*9880d681SAndroid Build Coastguard Worker; Note that in this example, %P and %Q could in fact be the same
243*9880d681SAndroid Build Coastguard Worker; pointer.  %v could be different than the value observed for %a
244*9880d681SAndroid Build Coastguard Worker; and that's okay because we're using relaxed memory ordering.
245*9880d681SAndroid Build Coastguard Worker; The only guarantee we have to provide is that each of the loads
246*9880d681SAndroid Build Coastguard Worker; has to observe some value written to that location.  We  do
247*9880d681SAndroid Build Coastguard Worker; not have to respect the order in which those writes were done.
248*9880d681SAndroid Build Coastguard Workerdefine i32 @dse5(i32 *%P, i32 *%Q) {
249*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @dse5
250*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store
251*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0
252*9880d681SAndroid Build Coastguard Worker  %v = load atomic i32, i32* %P unordered, align 4
253*9880d681SAndroid Build Coastguard Worker  %a = load atomic i32, i32* %Q unordered, align 4
254*9880d681SAndroid Build Coastguard Worker  store atomic i32 %v, i32* %P unordered, align 4
255*9880d681SAndroid Build Coastguard Worker  %b = load atomic i32, i32* %Q unordered, align 4
256*9880d681SAndroid Build Coastguard Worker  %res = sub i32 %a, %b
257*9880d681SAndroid Build Coastguard Worker  ret i32 %res
258*9880d681SAndroid Build Coastguard Worker}
259*9880d681SAndroid Build Coastguard Worker
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Workerdefine void @dse_neg1(i32 *%P) {
262*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @dse_neg1
263*9880d681SAndroid Build Coastguard Worker; CHECK: store
264*9880d681SAndroid Build Coastguard Worker  %v = load i32, i32* %P
265*9880d681SAndroid Build Coastguard Worker  store i32 5, i32* %P
266*9880d681SAndroid Build Coastguard Worker  ret void
267*9880d681SAndroid Build Coastguard Worker}
268*9880d681SAndroid Build Coastguard Worker
269*9880d681SAndroid Build Coastguard Worker; Could remove the store, but only if ordering was somehow
270*9880d681SAndroid Build Coastguard Worker; encoded.
271*9880d681SAndroid Build Coastguard Workerdefine void @dse_neg2(i32 *%P) {
272*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @dse_neg2
273*9880d681SAndroid Build Coastguard Worker; CHECK: store
274*9880d681SAndroid Build Coastguard Worker  %v = load i32, i32* %P
275*9880d681SAndroid Build Coastguard Worker  store atomic i32 %v, i32* %P seq_cst, align 4
276*9880d681SAndroid Build Coastguard Worker  ret void
277*9880d681SAndroid Build Coastguard Worker}
278*9880d681SAndroid Build Coastguard Worker
279