Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / Analysis / BasicAA / gep-alias.ll
blob30298625426641926520ee193519fef5d42664ea
1 ; RUN: opt < %s -aa-pipeline=basic-aa -passes=gvn,instcombine -S 2>&1 | FileCheck %s
3 target datalayout = "e-p:32:32:32-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
5 ; Make sure that basicaa thinks R and r are must aliases.
6 define i32 @test1(ptr %P) {
7 entry:
8         %R = getelementptr {i32, i32}, ptr %P, i32 0, i32 1
9         %S = load i32, ptr %R
11         %r = getelementptr {i32, i32}, ptr %P, i32 0, i32 1
12         %s = load i32, ptr %r
14         %t = sub i32 %S, %s
15         ret i32 %t
16 ; CHECK-LABEL: @test1(
17 ; CHECK: ret i32 0
20 define i32 @test2(ptr %P) {
21 entry:
22         %R = getelementptr {i32, i32, i32}, ptr %P, i32 0, i32 1
23         %S = load i32, ptr %R
25         %r = getelementptr {i32, i32, i32}, ptr %P, i32 0, i32 2
26   store i32 42, ptr %r
28         %s = load i32, ptr %R
30         %t = sub i32 %S, %s
31         ret i32 %t
32 ; CHECK-LABEL: @test2(
33 ; CHECK: ret i32 0
37 ; This was a miscompilation.
38 define i32 @test3(ptr %P) {
39 entry:
40   %P2 = getelementptr {float, {i32, i32, i32}}, ptr %P, i32 0, i32 1
41         %R = getelementptr {i32, i32, i32}, ptr %P2, i32 0, i32 1
42         %S = load i32, ptr %R
44         %r = getelementptr {i32, i32, i32}, ptr %P2, i32 0, i32 2
45   store i32 42, ptr %r
47         %s = load i32, ptr %R
49         %t = sub i32 %S, %s
50         ret i32 %t
51 ; CHECK-LABEL: @test3(
52 ; CHECK: ret i32 0
56 ;; This is reduced from the SmallPtrSet constructor.
57 %SmallPtrSetImpl = type { ptr, i32, i32, i32, [1 x ptr] }
58 %SmallPtrSet64 = type { %SmallPtrSetImpl, [64 x ptr] }
60 define i32 @test4(ptr %P) {
61 entry:
62   %tmp2 = getelementptr inbounds %SmallPtrSet64, ptr %P, i64 0, i32 0, i32 1
63   store i32 64, ptr %tmp2, align 8
64   %tmp3 = getelementptr inbounds %SmallPtrSet64, ptr %P, i64 0, i32 0, i32 4, i64 64
65   store ptr null, ptr %tmp3, align 8
66   %tmp4 = load i32, ptr %tmp2, align 8
67         ret i32 %tmp4
68 ; CHECK-LABEL: @test4(
69 ; CHECK: ret i32 64
72 ; P[i] != p[i+1]
73 define i32 @test5(ptr %p, i64 %i) {
74   %pi = getelementptr i32, ptr %p, i64 %i
75   %i.next = add i64 %i, 1
76   %pi.next = getelementptr i32, ptr %p, i64 %i.next
77   %x = load i32, ptr %pi
78   store i32 42, ptr %pi.next
79   %y = load i32, ptr %pi
80   %z = sub i32 %x, %y
81   ret i32 %z
82 ; CHECK-LABEL: @test5(
83 ; CHECK: ret i32 0
86 define i32 @test5_as1_smaller_size(ptr addrspace(1) %p, i8 %i) {
87   %pi = getelementptr i32, ptr addrspace(1) %p, i8 %i
88   %i.next = add i8 %i, 1
89   %pi.next = getelementptr i32, ptr addrspace(1) %p, i8 %i.next
90   %x = load i32, ptr addrspace(1) %pi
91   store i32 42, ptr addrspace(1) %pi.next
92   %y = load i32, ptr addrspace(1) %pi
93   %z = sub i32 %x, %y
94   ret i32 %z
95 ; CHECK-LABEL: @test5_as1_smaller_size(
96 ; CHECK: sext
97 ; CHECK: ret i32 0
100 define i32 @test5_as1_same_size(ptr addrspace(1) %p, i16 %i) {
101   %pi = getelementptr i32, ptr addrspace(1) %p, i16 %i
102   %i.next = add i16 %i, 1
103   %pi.next = getelementptr i32, ptr addrspace(1) %p, i16 %i.next
104   %x = load i32, ptr addrspace(1) %pi
105   store i32 42, ptr addrspace(1) %pi.next
106   %y = load i32, ptr addrspace(1) %pi
107   %z = sub i32 %x, %y
108   ret i32 %z
109 ; CHECK-LABEL: @test5_as1_same_size(
110 ; CHECK: ret i32 0
113 ; P[i] != p[(i*4)|1]
114 define i32 @test6(ptr %p, i64 %i1) {
115   %i = shl i64 %i1, 2
116   %pi = getelementptr i32, ptr %p, i64 %i
117   %i.next = or i64 %i, 1
118   %pi.next = getelementptr i32, ptr %p, i64 %i.next
119   %x = load i32, ptr %pi
120   store i32 42, ptr %pi.next
121   %y = load i32, ptr %pi
122   %z = sub i32 %x, %y
123   ret i32 %z
124 ; CHECK-LABEL: @test6(
125 ; CHECK: ret i32 0
128 ; P[1] != P[i*4]
129 define i32 @test7(ptr %p, i64 %i) {
130   %pi = getelementptr i32, ptr %p, i64 1
131   %i.next = shl i64 %i, 2
132   %pi.next = getelementptr i32, ptr %p, i64 %i.next
133   %x = load i32, ptr %pi
134   store i32 42, ptr %pi.next
135   %y = load i32, ptr %pi
136   %z = sub i32 %x, %y
137   ret i32 %z
138 ; CHECK-LABEL: @test7(
139 ; CHECK: ret i32 0
142 ; P[zext(i)] != p[zext(i+1)]
143 ; PR1143
144 define i32 @test8(ptr %p, i16 %i) {
145   %i1 = zext i16 %i to i32
146   %pi = getelementptr i32, ptr %p, i32 %i1
147   %i.next = add i16 %i, 1
148   %i.next2 = zext i16 %i.next to i32
149   %pi.next = getelementptr i32, ptr %p, i32 %i.next2
150   %x = load i32, ptr %pi
151   store i32 42, ptr %pi.next
152   %y = load i32, ptr %pi
153   %z = sub i32 %x, %y
154   ret i32 %z
155 ; CHECK-LABEL: @test8(
156 ; CHECK: ret i32 0
159 define i8 @test9(ptr %P, i32 %i, i32 %j) {
160   %i2 = shl i32 %i, 2
161   %i3 = add i32 %i2, 1
162   ; P2 = P + 1 + 4*i
163   %P2 = getelementptr [4 x i8], ptr %P, i32 0, i32 %i3
165   %j2 = shl i32 %j, 2
167   ; P4 = P + 4*j
168   %P4 = getelementptr [4 x i8], ptr %P, i32 0, i32 %j2
170   %x = load i8, ptr %P2
171   store i8 42, ptr %P4
172   %y = load i8, ptr %P2
173   %z = sub i8 %x, %y
174   ret i8 %z
175 ; CHECK-LABEL: @test9(
176 ; CHECK: ret i8 0
179 define i8 @test10(ptr %P, i32 %i) {
180   %i2 = shl i32 %i, 2
181   %i3 = add i32 %i2, 4
182   ; P2 = P + 4 + 4*i
183   %P2 = getelementptr [4 x i8], ptr %P, i32 0, i32 %i3
185   ; P4 = P + 4*i
186   %P4 = getelementptr [4 x i8], ptr %P, i32 0, i32 %i2
188   %x = load i8, ptr %P2
189   store i8 42, ptr %P4
190   %y = load i8, ptr %P2
191   %z = sub i8 %x, %y
192   ret i8 %z
193 ; CHECK-LABEL: @test10(
194 ; CHECK: ret i8 0
197 ; (This was a miscompilation.)
198 define float @test11(i32 %indvar, ptr %q) nounwind ssp {
199   %tmp = mul i32 %indvar, -1
200   %dec = add i32 %tmp, 3
201   %scevgep = getelementptr [4 x [2 x float]], ptr %q, i32 0, i32 %dec
202   %y29 = getelementptr inbounds [2 x float], ptr %q, i32 0, i32 1
203   store float 1.0, ptr %y29, align 4
204   store i64 0, ptr %scevgep, align 4
205   %tmp30 = load float, ptr %y29, align 4
206   ret float %tmp30
207 ; CHECK-LABEL: @test11(
208 ; CHECK: ret float %tmp30
211 ; (This was a miscompilation.)
212 define i32 @test12(i32 %x, i32 %y, ptr %p) nounwind {
213   %b = getelementptr [13 x i8], ptr %p, i32 %x
214   %d = getelementptr [15 x i8], ptr %b, i32 %y, i32 8
215   store i32 1, ptr %p
216   store i32 0, ptr %d
217   %r = load i32, ptr %p
218   ret i32 %r
219 ; CHECK-LABEL: @test12(
220 ; CHECK: ret i32 %r
223 @P = internal global i32 715827882, align 4
224 @Q = internal global i32 715827883, align 4
225 @.str = private unnamed_addr constant [7 x i8] c"%u %u\0A\00", align 1
227 ; Make sure we recognize that u[0] and u[Global + Cst] may alias
228 ; when the addition has wrapping semantic.
229 ; PR24468.
230 ; CHECK-LABEL: @test13(
231 ; Make sure the stores appear before the related loads.
232 ; CHECK: store i8 42,
233 ; CHECK: store i8 99,
234 ; Find the loads and make sure they are used in the arguments to the printf.
235 ; CHECK: [[T0:%[a-zA-Z0-9_]+]] = load i8, ptr %t, align 1
236 ; CHECK: [[T0ARG:%[a-zA-Z0-9_]+]] = zext i8 [[T0]] to i32
237 ; CHECK: [[U0:%[a-zA-Z0-9_]+]] = load i8, ptr %u, align 1
238 ; CHECK: [[U0ARG:%[a-zA-Z0-9_]+]] = zext i8 [[U0]] to i32
239 ; CHECK: call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str, i32 [[T0ARG]], i32 [[U0ARG]])
240 ; CHECK: ret
241 define void @test13() {
242 entry:
243   %t = alloca [3 x i8], align 1
244   %u = alloca [3 x i8], align 1
245   %tmp = load i32, ptr @P, align 4
246   %tmp1 = mul i32 %tmp, 3
247   %mul = add i32 %tmp1, -2147483646
248   %idxprom = zext i32 %mul to i64
249   %arrayidx = getelementptr inbounds [3 x i8], ptr %t, i64 0, i64 %idxprom
250   store i8 42, ptr %arrayidx, align 1
251   %tmp2 = load i32, ptr @Q, align 4
252   %tmp3 = mul i32 %tmp2, 3
253   %mul2 = add i32 %tmp3, 2147483647
254   %idxprom3 = zext i32 %mul2 to i64
255   %arrayidx4 = getelementptr inbounds [3 x i8], ptr %u, i64 0, i64 %idxprom3
256   store i8 99, ptr %arrayidx4, align 1
257   %tmp4 = load i8, ptr %t, align 1
258   %conv = zext i8 %tmp4 to i32
259   %tmp5 = load i8, ptr %u, align 1
260   %conv7 = zext i8 %tmp5 to i32
261   %call = call i32 (ptr, ...) @printf(ptr @.str, i32 %conv, i32 %conv7)
262   ret void
265 declare i32 @printf(ptr, ...)