Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Analysis / BasicAA / gep-alias.ll
blob132cc496b8f7d9eac627f53d7aa8b00727a82d52
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 disjoint 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[i] != p[(i*4)|2048] with disjoint or
129 define i32 @test6_higheror(ptr %p, i64 %i1) {
130   %i = shl nuw nsw i64 %i1, 2
131   %pi = getelementptr i32, ptr %p, i64 %i
132   %i.next = or disjoint i64 %i, 2048
133   %pi.next = getelementptr i32, ptr %p, i64 %i.next
134   %x = load i32, ptr %pi
135   store i32 42, ptr %pi.next
136   %y = load i32, ptr %pi
137   %z = sub i32 %x, %y
138   ret i32 %z
139 ; CHECK-LABEL: @test6_higheror(
140 ; CHECK: ret i32 0
143 ; P[1] != P[i*4]
144 define i32 @test7(ptr %p, i64 %i) {
145   %pi = getelementptr i32, ptr %p, i64 1
146   %i.next = shl i64 %i, 2
147   %pi.next = getelementptr i32, ptr %p, i64 %i.next
148   %x = load i32, ptr %pi
149   store i32 42, ptr %pi.next
150   %y = load i32, ptr %pi
151   %z = sub i32 %x, %y
152   ret i32 %z
153 ; CHECK-LABEL: @test7(
154 ; CHECK: ret i32 0
157 ; P[zext(i)] != p[zext(i+1)]
158 ; PR1143
159 define i32 @test8(ptr %p, i16 %i) {
160   %i1 = zext i16 %i to i32
161   %pi = getelementptr i32, ptr %p, i32 %i1
162   %i.next = add i16 %i, 1
163   %i.next2 = zext i16 %i.next to i32
164   %pi.next = getelementptr i32, ptr %p, i32 %i.next2
165   %x = load i32, ptr %pi
166   store i32 42, ptr %pi.next
167   %y = load i32, ptr %pi
168   %z = sub i32 %x, %y
169   ret i32 %z
170 ; CHECK-LABEL: @test8(
171 ; CHECK: ret i32 0
174 define i8 @test9(ptr %P, i32 %i, i32 %j) {
175   %i2 = shl i32 %i, 2
176   %i3 = add i32 %i2, 1
177   ; P2 = P + 1 + 4*i
178   %P2 = getelementptr [4 x i8], ptr %P, i32 0, i32 %i3
180   %j2 = shl i32 %j, 2
182   ; P4 = P + 4*j
183   %P4 = getelementptr [4 x i8], ptr %P, i32 0, i32 %j2
185   %x = load i8, ptr %P2
186   store i8 42, ptr %P4
187   %y = load i8, ptr %P2
188   %z = sub i8 %x, %y
189   ret i8 %z
190 ; CHECK-LABEL: @test9(
191 ; CHECK: ret i8 0
194 define i8 @test10(ptr %P, i32 %i) {
195   %i2 = shl i32 %i, 2
196   %i3 = add i32 %i2, 4
197   ; P2 = P + 4 + 4*i
198   %P2 = getelementptr [4 x i8], ptr %P, i32 0, i32 %i3
200   ; P4 = P + 4*i
201   %P4 = getelementptr [4 x i8], ptr %P, i32 0, i32 %i2
203   %x = load i8, ptr %P2
204   store i8 42, ptr %P4
205   %y = load i8, ptr %P2
206   %z = sub i8 %x, %y
207   ret i8 %z
208 ; CHECK-LABEL: @test10(
209 ; CHECK: ret i8 0
212 ; (This was a miscompilation.)
213 define float @test11(i32 %indvar, ptr %q) nounwind ssp {
214   %tmp = mul i32 %indvar, -1
215   %dec = add i32 %tmp, 3
216   %scevgep = getelementptr [4 x [2 x float]], ptr %q, i32 0, i32 %dec
217   %y29 = getelementptr inbounds [2 x float], ptr %q, i32 0, i32 1
218   store float 1.0, ptr %y29, align 4
219   store i64 0, ptr %scevgep, align 4
220   %tmp30 = load float, ptr %y29, align 4
221   ret float %tmp30
222 ; CHECK-LABEL: @test11(
223 ; CHECK: ret float %tmp30
226 ; (This was a miscompilation.)
227 define i32 @test12(i32 %x, i32 %y, ptr %p) nounwind {
228   %b = getelementptr [13 x i8], ptr %p, i32 %x
229   %d = getelementptr [15 x i8], ptr %b, i32 %y, i32 8
230   store i32 1, ptr %p
231   store i32 0, ptr %d
232   %r = load i32, ptr %p
233   ret i32 %r
234 ; CHECK-LABEL: @test12(
235 ; CHECK: ret i32 %r
238 @P = internal global i32 715827882, align 4
239 @Q = internal global i32 715827883, align 4
240 @.str = private unnamed_addr constant [7 x i8] c"%u %u\0A\00", align 1
242 ; Make sure we recognize that u[0] and u[Global + Cst] may alias
243 ; when the addition has wrapping semantic.
244 ; PR24468.
245 ; CHECK-LABEL: @test13(
246 ; Make sure the stores appear before the related loads.
247 ; CHECK: store i8 42,
248 ; CHECK: store i8 99,
249 ; Find the loads and make sure they are used in the arguments to the printf.
250 ; CHECK: [[T0:%[a-zA-Z0-9_]+]] = load i8, ptr %t, align 1
251 ; CHECK: [[T0ARG:%[a-zA-Z0-9_]+]] = zext i8 [[T0]] to i32
252 ; CHECK: [[U0:%[a-zA-Z0-9_]+]] = load i8, ptr %u, align 1
253 ; CHECK: [[U0ARG:%[a-zA-Z0-9_]+]] = zext i8 [[U0]] to i32
254 ; CHECK: call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str, i32 [[T0ARG]], i32 [[U0ARG]])
255 ; CHECK: ret
256 define void @test13() {
257 entry:
258   %t = alloca [3 x i8], align 1
259   %u = alloca [3 x i8], align 1
260   %tmp = load i32, ptr @P, align 4
261   %tmp1 = mul i32 %tmp, 3
262   %mul = add i32 %tmp1, -2147483646
263   %idxprom = zext i32 %mul to i64
264   %arrayidx = getelementptr inbounds [3 x i8], ptr %t, i64 0, i64 %idxprom
265   store i8 42, ptr %arrayidx, align 1
266   %tmp2 = load i32, ptr @Q, align 4
267   %tmp3 = mul i32 %tmp2, 3
268   %mul2 = add i32 %tmp3, 2147483647
269   %idxprom3 = zext i32 %mul2 to i64
270   %arrayidx4 = getelementptr inbounds [3 x i8], ptr %u, i64 0, i64 %idxprom3
271   store i8 99, ptr %arrayidx4, align 1
272   %tmp4 = load i8, ptr %t, align 1
273   %conv = zext i8 %tmp4 to i32
274   %tmp5 = load i8, ptr %u, align 1
275   %conv7 = zext i8 %tmp5 to i32
276   %call = call i32 (ptr, ...) @printf(ptr @.str, i32 %conv, i32 %conv7)
277   ret void
280 declare i32 @printf(ptr, ...)