xref: /aosp_15_r20/external/llvm/test/Analysis/BasicAA/modref.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -basicaa -gvn -dse -S | FileCheck %s
2*9880d681SAndroid Build Coastguard Workertarget datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.lifetime.end(i64, i8* nocapture)
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Workerdeclare void @external(i32*)
7*9880d681SAndroid Build Coastguard Worker
8*9880d681SAndroid Build Coastguard Workerdefine i32 @test0(i8* %P) {
9*9880d681SAndroid Build Coastguard Worker  %A = alloca i32
10*9880d681SAndroid Build Coastguard Worker  call void @external(i32* %A)
11*9880d681SAndroid Build Coastguard Worker
12*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %A
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i32(i8* %P, i8 0, i32 42, i32 1, i1 false)
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker  %B = load i32, i32* %A
17*9880d681SAndroid Build Coastguard Worker  ret i32 %B
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test0
20*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0
21*9880d681SAndroid Build Coastguard Worker}
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Workerdefine i8 @test1() {
24*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1
25*9880d681SAndroid Build Coastguard Worker  %A = alloca i8
26*9880d681SAndroid Build Coastguard Worker  %B = alloca i8
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker  store i8 2, i8* %B  ;; Not written to by memcpy
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i8(i8* %A, i8* %B, i8 -1, i32 0, i1 false)
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker  %C = load i8, i8* %B
33*9880d681SAndroid Build Coastguard Worker  ret i8 %C
34*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 2
35*9880d681SAndroid Build Coastguard Worker}
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Workerdefine i8 @test2(i8* %P) {
38*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2
39*9880d681SAndroid Build Coastguard Worker  %P2 = getelementptr i8, i8* %P, i32 127
40*9880d681SAndroid Build Coastguard Worker  store i8 1, i8* %P2  ;; Not dead across memset
41*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i8(i8* %P, i8 2, i8 127, i32 0, i1 false)
42*9880d681SAndroid Build Coastguard Worker  %A = load i8, i8* %P2
43*9880d681SAndroid Build Coastguard Worker  ret i8 %A
44*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 1
45*9880d681SAndroid Build Coastguard Worker}
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Workerdefine i8 @test2a(i8* %P) {
48*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2
49*9880d681SAndroid Build Coastguard Worker  %P2 = getelementptr i8, i8* %P, i32 126
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker  ;; FIXME: DSE isn't zapping this dead store.
52*9880d681SAndroid Build Coastguard Worker  store i8 1, i8* %P2  ;; Dead, clobbered by memset.
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i8(i8* %P, i8 2, i8 127, i32 0, i1 false)
55*9880d681SAndroid Build Coastguard Worker  %A = load i8, i8* %P2
56*9880d681SAndroid Build Coastguard Worker  ret i8 %A
57*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load
58*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 2
59*9880d681SAndroid Build Coastguard Worker}
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Workerdefine void @test3(i8* %P, i8 %X) {
62*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3
63*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store
64*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %Y
65*9880d681SAndroid Build Coastguard Worker  %Y = add i8 %X, 1     ;; Dead, because the only use (the store) is dead.
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker  %P2 = getelementptr i8, i8* %P, i32 2
68*9880d681SAndroid Build Coastguard Worker  store i8 %Y, i8* %P2  ;; Not read by lifetime.end, should be removed.
69*9880d681SAndroid Build Coastguard Worker; CHECK: store i8 2, i8* %P2
70*9880d681SAndroid Build Coastguard Worker  call void @llvm.lifetime.end(i64 1, i8* %P)
71*9880d681SAndroid Build Coastguard Worker  store i8 2, i8* %P2
72*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: store
73*9880d681SAndroid Build Coastguard Worker  ret void
74*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
75*9880d681SAndroid Build Coastguard Worker}
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Workerdefine void @test3a(i8* %P, i8 %X) {
78*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test3a
79*9880d681SAndroid Build Coastguard Worker  %Y = add i8 %X, 1     ;; Dead, because the only use (the store) is dead.
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker  %P2 = getelementptr i8, i8* %P, i32 2
82*9880d681SAndroid Build Coastguard Worker  store i8 %Y, i8* %P2
83*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.lifetime.end
84*9880d681SAndroid Build Coastguard Worker  call void @llvm.lifetime.end(i64 10, i8* %P)
85*9880d681SAndroid Build Coastguard Worker  ret void
86*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
87*9880d681SAndroid Build Coastguard Worker}
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Worker@G1 = external global i32
90*9880d681SAndroid Build Coastguard Worker@G2 = external global [4000 x i32]
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Workerdefine i32 @test4(i8* %P) {
93*9880d681SAndroid Build Coastguard Worker  %tmp = load i32, i32* @G1
94*9880d681SAndroid Build Coastguard Worker  call void @llvm.memset.p0i8.i32(i8* bitcast ([4000 x i32]* @G2 to i8*), i8 0, i32 4000, i32 1, i1 false)
95*9880d681SAndroid Build Coastguard Worker  %tmp2 = load i32, i32* @G1
96*9880d681SAndroid Build Coastguard Worker  %sub = sub i32 %tmp2, %tmp
97*9880d681SAndroid Build Coastguard Worker  ret i32 %sub
98*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4
99*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load
100*9880d681SAndroid Build Coastguard Worker; CHECK: memset.p0i8.i32
101*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load
102*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0
103*9880d681SAndroid Build Coastguard Worker}
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker; Verify that basicaa is handling variable length memcpy, knowing it doesn't
106*9880d681SAndroid Build Coastguard Worker; write to G1.
107*9880d681SAndroid Build Coastguard Workerdefine i32 @test5(i8* %P, i32 %Len) {
108*9880d681SAndroid Build Coastguard Worker  %tmp = load i32, i32* @G1
109*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast ([4000 x i32]* @G2 to i8*), i8* bitcast (i32* @G1 to i8*), i32 %Len, i32 1, i1 false)
110*9880d681SAndroid Build Coastguard Worker  %tmp2 = load i32, i32* @G1
111*9880d681SAndroid Build Coastguard Worker  %sub = sub i32 %tmp2, %tmp
112*9880d681SAndroid Build Coastguard Worker  ret i32 %sub
113*9880d681SAndroid Build Coastguard Worker; CHECK: @test5
114*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load
115*9880d681SAndroid Build Coastguard Worker; CHECK: memcpy.p0i8.p0i8.i32
116*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load
117*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0
118*9880d681SAndroid Build Coastguard Worker}
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Workerdefine i8 @test6(i8* %p, i8* noalias %a) {
121*9880d681SAndroid Build Coastguard Worker  %x = load i8, i8* %a
122*9880d681SAndroid Build Coastguard Worker  %t = va_arg i8* %p, float
123*9880d681SAndroid Build Coastguard Worker  %y = load i8, i8* %a
124*9880d681SAndroid Build Coastguard Worker  %z = add i8 %x, %y
125*9880d681SAndroid Build Coastguard Worker  ret i8 %z
126*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6
127*9880d681SAndroid Build Coastguard Worker; CHECK: load i8, i8* %a
128*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load
129*9880d681SAndroid Build Coastguard Worker; CHECK: ret
130*9880d681SAndroid Build Coastguard Worker}
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Worker; PR10628
133*9880d681SAndroid Build Coastguard Workerdeclare void @test7decl(i32* nocapture %x)
134*9880d681SAndroid Build Coastguard Workerdefine i32 @test7() nounwind uwtable ssp {
135*9880d681SAndroid Build Coastguard Workerentry:
136*9880d681SAndroid Build Coastguard Worker  %x = alloca i32, align 4
137*9880d681SAndroid Build Coastguard Worker  store i32 0, i32* %x, align 4
138*9880d681SAndroid Build Coastguard Worker  %add.ptr = getelementptr inbounds i32, i32* %x, i64 1
139*9880d681SAndroid Build Coastguard Worker  call void @test7decl(i32* %add.ptr)
140*9880d681SAndroid Build Coastguard Worker  %tmp = load i32, i32* %x, align 4
141*9880d681SAndroid Build Coastguard Worker  ret i32 %tmp
142*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test7(
143*9880d681SAndroid Build Coastguard Worker; CHECK: store i32 0
144*9880d681SAndroid Build Coastguard Worker; CHECK: call void @test7decl
145*9880d681SAndroid Build Coastguard Worker; CHECK: load i32, i32*
146*9880d681SAndroid Build Coastguard Worker}
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker;; Check that aa correctly handles functions marked with argmemonly
149*9880d681SAndroid Build Coastguard Worker;; attribute.
150*9880d681SAndroid Build Coastguard Workerdeclare i32 @func_argmemonly(i32 * %P) argmemonly
151*9880d681SAndroid Build Coastguard Worker
152*9880d681SAndroid Build Coastguard Worker;; Can not remove redundant load, function may write to it.
153*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test8(
154*9880d681SAndroid Build Coastguard Workerdefine i32 @test8(i32 *%P) {
155*9880d681SAndroid Build Coastguard Worker  %V1 = load i32, i32* %P
156*9880d681SAndroid Build Coastguard Worker  call i32 @func_argmemonly(i32* %P)
157*9880d681SAndroid Build Coastguard Worker  %V2 = load i32, i32* %P
158*9880d681SAndroid Build Coastguard Worker  %Diff = sub i32 %V1, %V2
159*9880d681SAndroid Build Coastguard Worker  ret i32 %Diff
160*9880d681SAndroid Build Coastguard Worker  ; CHECK: load
161*9880d681SAndroid Build Coastguard Worker  ; CHECK: load
162*9880d681SAndroid Build Coastguard Worker  ; CHECK: sub
163*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 %Diff
164*9880d681SAndroid Build Coastguard Worker}
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Worker;; In this case load can be removed, function clobbers only %P2.
167*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test9(
168*9880d681SAndroid Build Coastguard Workerdefine i32 @test9(i32* %P, i32* noalias %P2) {
169*9880d681SAndroid Build Coastguard Worker  %V1 = load i32, i32* %P
170*9880d681SAndroid Build Coastguard Worker  call i32 @func_argmemonly(i32* %P2)
171*9880d681SAndroid Build Coastguard Worker  %V2 = load i32, i32* %P
172*9880d681SAndroid Build Coastguard Worker  %Diff = sub i32 %V1, %V2
173*9880d681SAndroid Build Coastguard Worker  ret i32 %Diff
174*9880d681SAndroid Build Coastguard Worker  ; CHECK-NOT: load
175*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 0
176*9880d681SAndroid Build Coastguard Worker}
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Worker;; In this case load can *not* be removed. Function clobers only %P2 but it may
179*9880d681SAndroid Build Coastguard Worker;; alias with %P.
180*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test10(
181*9880d681SAndroid Build Coastguard Workerdefine i32 @test10(i32* %P, i32* %P2) {
182*9880d681SAndroid Build Coastguard Worker  %V1 = load i32, i32* %P
183*9880d681SAndroid Build Coastguard Worker  call i32 @func_argmemonly(i32* %P2)
184*9880d681SAndroid Build Coastguard Worker  %V2 = load i32, i32* %P
185*9880d681SAndroid Build Coastguard Worker  %Diff = sub i32 %V1, %V2
186*9880d681SAndroid Build Coastguard Worker  ret i32 %Diff
187*9880d681SAndroid Build Coastguard Worker  ; CHECK: load
188*9880d681SAndroid Build Coastguard Worker  ; CHECK: load
189*9880d681SAndroid Build Coastguard Worker  ; CHECK: sub
190*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 %Diff
191*9880d681SAndroid Build Coastguard Worker}
192*9880d681SAndroid Build Coastguard Worker
193*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test11(
194*9880d681SAndroid Build Coastguard Workerdefine i32 @test11(i32* %P, i32* %P2) {
195*9880d681SAndroid Build Coastguard Worker  %V1 = load i32, i32* %P
196*9880d681SAndroid Build Coastguard Worker  call i32 @func_argmemonly(i32* readonly %P2)
197*9880d681SAndroid Build Coastguard Worker  %V2 = load i32, i32* %P
198*9880d681SAndroid Build Coastguard Worker  %Diff = sub i32 %V1, %V2
199*9880d681SAndroid Build Coastguard Worker  ret i32 %Diff
200*9880d681SAndroid Build Coastguard Worker  ; CHECK-NOT: load
201*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 0
202*9880d681SAndroid Build Coastguard Worker}
203*9880d681SAndroid Build Coastguard Worker
204*9880d681SAndroid Build Coastguard Workerdeclare i32 @func_argmemonly_two_args(i32* %P, i32* %P2) argmemonly
205*9880d681SAndroid Build Coastguard Worker
206*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test12(
207*9880d681SAndroid Build Coastguard Workerdefine i32 @test12(i32* %P, i32* %P2, i32* %P3) {
208*9880d681SAndroid Build Coastguard Worker  %V1 = load i32, i32* %P
209*9880d681SAndroid Build Coastguard Worker  call i32 @func_argmemonly_two_args(i32* readonly %P2, i32* %P3)
210*9880d681SAndroid Build Coastguard Worker  %V2 = load i32, i32* %P
211*9880d681SAndroid Build Coastguard Worker  %Diff = sub i32 %V1, %V2
212*9880d681SAndroid Build Coastguard Worker  ret i32 %Diff
213*9880d681SAndroid Build Coastguard Worker  ; CHECK: load
214*9880d681SAndroid Build Coastguard Worker  ; CHECK: load
215*9880d681SAndroid Build Coastguard Worker  ; CHECK: sub
216*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 %Diff
217*9880d681SAndroid Build Coastguard Worker}
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test13(
220*9880d681SAndroid Build Coastguard Workerdefine i32 @test13(i32* %P, i32* %P2) {
221*9880d681SAndroid Build Coastguard Worker  %V1 = load i32, i32* %P
222*9880d681SAndroid Build Coastguard Worker  call i32 @func_argmemonly(i32* readnone %P2)
223*9880d681SAndroid Build Coastguard Worker  %V2 = load i32, i32* %P
224*9880d681SAndroid Build Coastguard Worker  %Diff = sub i32 %V1, %V2
225*9880d681SAndroid Build Coastguard Worker  ret i32 %Diff
226*9880d681SAndroid Build Coastguard Worker  ; CHECK-NOT: load
227*9880d681SAndroid Build Coastguard Worker  ; CHECK: ret i32 0
228*9880d681SAndroid Build Coastguard Worker}
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
231*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memset.p0i8.i8(i8* nocapture, i8, i8, i32, i1) nounwind
232*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memcpy.p0i8.p0i8.i8(i8* nocapture, i8* nocapture, i8, i32, i1) nounwind
233*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
234