Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Analysis / BasicAA / range.ll
blobe5dfb60c8b8784b8747731e6fd26c694cceeca40
1 ; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
3 %struct.S = type { i32, [2 x i32], i32 }
4 %struct.S2 = type { i32, [4 x i32], [4 x i32] }
5 @G = global [10 x i32] zeroinitializer, align 4
7 ; CHECK: Function: t1
8 ; CHECK: NoAlias: i32* %gep1, i32* %gep2
9 define void @t1(ptr %s) {
10   %gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 1
11   %gep2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 0
12   load i32, ptr %gep1
13   load i32, ptr %gep2
14   ret void
17 ; CHECK: Function: t2_fwd
18 ; CHECK: MayAlias: i32* %gep1, i32* %gep2
19 define void @t2_fwd(ptr %s, ptr %q) {
20   %in_array = load i32, ptr %q, !range !0
21   %gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %in_array
22   %gep2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 0
23   load i32, ptr %gep1
24   load i32, ptr %gep2
25   ret void
28 ; CHECK: Function: t2_rev
29 ; CHECK: MayAlias: i32* %gep1, i32* %gep2
30 define void @t2_rev(ptr %s, ptr %q) {
31   %in_array = load i32, ptr %q, !range !0
32   %gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 0
33   %gep2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %in_array
34   load i32, ptr %gep1
35   load i32, ptr %gep2
36   ret void
39 ; CHECK: Function: t3_fwd
40 ; CHECK: NoAlias: i32* %gep1, i32* %gep2
41 define void @t3_fwd(ptr %s, ptr %q) {
42   %knownzero = load i32, ptr %q, !range !1
43   %gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %knownzero
44   %gep2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 1
45   load i32, ptr %gep1
46   load i32, ptr %gep2
47   ret void
50 ; CHECK: Function: t3_rev
51 ; CHECK: NoAlias: i32* %gep1, i32* %gep2
52 define void @t3_rev(ptr %s, ptr %q) {
53   %knownzero = load i32, ptr %q, !range !1
54   %gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 1
55   %gep2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %knownzero
56   load i32, ptr %gep1
57   load i32, ptr %gep2
58   ret void
61 ; CHECK: Function: member_after
62 ; CHECK: NoAlias: i32* %gep1, i32* %gep2
63 define void @member_after(ptr %s, ptr %q) {
64   %in_array = load i32, ptr %q, !range !0
65   %gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %in_array
66   %gep2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2
67   load i32, ptr %gep1
68   load i32, ptr %gep2
69   ret void
72 ; CHECK: Function: member_after_rev
73 ; CHECK: NoAlias: i32* %gep1, i32* %gep2
74 define void @member_after_rev(ptr %s, ptr %q) {
75   %in_array = load i32, ptr %q, !range !0
76   %gep2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2
77   %gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %in_array
78   load i32, ptr %gep1
79   load i32, ptr %gep2
80   ret void
83 ; CHECK: Function: member_before
84 ; CHECK: NoAlias: i32* %gep1, i32* %s
85 define void @member_before(ptr %s, ptr %q) {
86   %in_array = load i32, ptr %q, !range !0
87   %gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %in_array
88   load i32, ptr %gep1
89   load i32, ptr %s
90   ret void
93 ; CHECK: Function: member_before_rev
94 ; CHECK: NoAlias: i32* %gep1, i32* %s
95 define void @member_before_rev(ptr %s, ptr %q) {
96   %in_array = load i32, ptr %q, !range !0
97   %gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1, i32 %in_array
98   load i32, ptr %gep1
99   load i32, ptr %s
100   ret void
103 ; CHECK-LABEL: Function: t5
104 ; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
105 ; CHECK: PartialAlias (off -4): i32* %gep2, %struct.S2* %s
106 ; CHECK: NoAlias: i32* %gep1, i32* %gep2
107 define void @t5(ptr %s, ptr %q) {
108   %in_array = load i32, ptr %q, !range !3
109   %gep1 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 %in_array
110   %gep2 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 1, i32 0
111   load %struct.S2, ptr %s
112   load i32, ptr %gep1
113   load i32, ptr %gep2
114   ret void
117 ; CHECK-LABEL: Function: t6
118 ; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
119 ; CHECK: PartialAlias (off -16): i32* %gep2, %struct.S2* %s
120 ; CHECK: MayAlias: i32* %gep1, i32* %gep2
121 define void @t6(ptr %s, ptr %q) {
122   %in_array = load i32, ptr %q, !range !3
123   %gep1 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 %in_array
124   %gep2 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 1, i32 3
125   load %struct.S2, ptr %s
126   load i32, ptr %gep1
127   load i32, ptr %gep2
128   ret void
131 ; CHECK-LABEL: Function: t7
132 ; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
133 ; CHECK: PartialAlias (off -20): i32* %gep2, %struct.S2* %s
134 ; CHECK: NoAlias: i32* %gep1, i32* %gep2
135 define void @t7(ptr %s, ptr %q) {
136   %in_array = load i32, ptr %q, !range !4
137   %gep1 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 %in_array
138   %gep2 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 0
139   load %struct.S2, ptr %s
140   load i32, ptr %gep1
141   load i32, ptr %gep2
142   ret void
145 ; CHECK-LABEL: Function: t8
146 ; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
147 ; CHECK: PartialAlias (off -24): i32* %gep2, %struct.S2* %s
148 ; CHECK: MayAlias: i32* %gep1, i32* %gep2
149 define void @t8(ptr %s, ptr %q) {
150   %in_array = load i32, ptr %q, !range !4
151   %gep1 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 %in_array
152   %gep2 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 1
153   load %struct.S2, ptr %s
154   load i32, ptr %q
155   load i32, ptr %gep1
156   load i32, ptr %gep2
157   ret void
160 ; CHECK-LABEL: Function: t9
161 ; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
162 ; CHECK: PartialAlias (off -20): i32* %gep2, %struct.S2* %s
163 ; CHECK: NoAlias: i32* %gep1, i32* %gep2
164 define void @t9(ptr %s, ptr %q) {
165   %in_array = load i32, ptr %q, !range !5
166   %gep1 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 1, i32 %in_array
167   %gep2 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 0
168   load %struct.S2, ptr %s
169   load i32, ptr %gep1
170   load i32, ptr %gep2
171   ret void
174 ; CHECK-LABEL: Function: t10
175 ; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
176 ; CHECK: PartialAlias (off -4): i32* %gep2, %struct.S2* %s
177 ; CHECK: MayAlias: i32* %gep1, i32* %gep2
178 define void @t10(ptr %s, ptr %q) {
179   %in_array = load i32, ptr %q, !range !5
180   %gep1 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 2, i32 %in_array
181   %gep2 = getelementptr inbounds %struct.S2, ptr %s, i64 0, i32 1, i32 0
182   load %struct.S2, ptr %s
183   load i32, ptr %gep1
184   load i32, ptr %gep2
185   ret void
188 ; CHECK-LABEL: Function: zeroext_index
189 ; CHECK:  MayAlias:     i32* %gep, [256 x i32]* %s
190 define void @zeroext_index(ptr %s, ptr %q) {
191   %a = load i8, ptr %q, !range !6
192   %in_array = zext i8 %a to i32
193   %gep = getelementptr inbounds [256 x i32], ptr %s, i64 0, i32 %in_array
194   load [256 x i32], ptr %s
195   load i32, ptr %gep
196   ret void
199 ; CHECK-LABEL: Function: multiple
200 ; CHECK: MayAlias: i32* %p, i32* %p.01
201 ; CHECK: MayAlias: i32* %p, i32* %p.02
202 ; CHECK: MayAlias: i32* %p.01, i32* %p.02
203 ; CHECK: NoAlias:  i32* %p.01, i32* %p.2
204 ; CHECK: MayAlias: i32* %p.02, i32* %p.2
205 ; CHECK: NoAlias:  i32* %p.01, i32* %p.3
206 ; CHECK: NoAlias:  i32* %p.02, i32* %p.3
207 define void @multiple(ptr %p, ptr %o1_ptr, ptr %o2_ptr) {
208   %o1 = load i32, ptr %o1_ptr, !range !0
209   %o2 = load i32, ptr %o2_ptr, !range !0
210   %p.01 = getelementptr i32, ptr %p, i32 %o1  ; p + [0, 1]
211   %p.02 = getelementptr i32, ptr %p.01, i32 %o2 ; p + [0, 2]
212   %p.2 = getelementptr i32, ptr %p, i32 2
213   %p.3 = getelementptr i32, ptr %p, i32 3
214   load i32, ptr %p
215   load i32, ptr %p.01
216   load i32, ptr %p.02
217   load i32, ptr %p.2
218   load i32, ptr %p.3
219   ret void
222 ; p.neg1 and p.o.1 don't alias, even though the addition o+1 may overflow.
223 ; While it makes INT_MIN a possible offset, offset -1 is not possible.
224 ; CHECK-LABEL: Function: benign_overflow
225 ; CHECK: MayAlias: i8* %p, i8* %p.o
226 ; CHECK: MayAlias: i8* %p.neg1, i8* %p.o
227 ; CHECK: MayAlias: i8* %p, i8* %p.o.1
228 ; CHECK: NoAlias: i8* %p.neg1, i8* %p.o.1
229 ; CHECK: NoAlias:  i8* %p.o, i8* %p.o.1
230 define void @benign_overflow(ptr %p, i64 %o) {
231   %c = icmp sge i64 %o, -1
232   call void @llvm.assume(i1 %c)
233   %p.neg1 = getelementptr i8, ptr %p, i64 -1
234   %p.o = getelementptr i8, ptr %p, i64 %o
235   %p.o.1 = getelementptr i8, ptr %p.o, i64 1
236   load i8, ptr %p
237   load i8, ptr %p.neg1
238   load i8, ptr %p.o
239   load i8, ptr %p.o.1
240   ret void
243 ; CHECK-LABEL: pr63266
244 ; CHECK: MayAlias:      i8* %gep2, i8* %offset16
245 define void @pr63266(i1 %c, ptr %base) {
246 entry:
247   %offset16 = getelementptr inbounds i8, ptr %base, i64 16
248   %gep1 = getelementptr i8, ptr %base, i64 -9223372036854775792
249   br i1 %c, label %if, label %join
252   br label %join
254 join:
255   %phi = phi i64 [ -9223372036854775808, %if ], [ 0, %entry ]
256   %gep2 = getelementptr i8, ptr %gep1, i64 %phi
257   store i8 0, ptr %gep2
258   load i8, ptr %offset16
259   ret void
263 ; CHECK-LABEL: Function: select_in_gep
264 ; CHECK: NoAlias: i32* %arrayidx, i32* getelementptr inbounds ([10 x i32], ptr @G, i64 0, i64 3)
265 define i32 @select_in_gep(i1 %c)  {
266 entry:
267   %select_ = select i1 %c, i64 2, i64 1
268   %arrayidx = getelementptr inbounds [10 x i32], ptr @G, i64 0, i64 %select_
269   store i32 42, ptr %arrayidx, align 4
270   %load_ = load i32, ptr getelementptr inbounds ([10 x i32], ptr @G, i64 0, i64 3), align 4
271   ret i32 %load_
274 declare void @llvm.assume(i1)
276 !0 = !{ i32 0, i32 2 }
277 !1 = !{ i32 0, i32 1 }
278 !2 = !{ i32 1, i32 2 }
279 !3 = !{ i32 -2, i32 0 }
280 !4 = !{ i32 1, i32 536870911 }
281 !5 = !{ i32 -536870911, i32 4 }
282 !6 = !{ i8 -2, i8 0 }