xref: /llvm-project/llvm/test/Analysis/BasicAA/q.bad.ll (revision 303c308e452c703c3d47940383ded3b2d3eefd56)
1; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
2target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
3target triple = "thumbv7--linux-gnueabi"
4
5; CHECK-LABEL: test_zext_sext_amounts255
6; CHECK: NoAlias: i8* %a, i8* %b
7define void @test_zext_sext_amounts255(ptr %mem) {
8  %sext.1 = sext i8 255 to i16
9  %sext.zext.1 = zext i16 %sext.1 to i64
10  %sext.2 = sext i8 255 to i32
11  %sext.zext.2 = zext i32 %sext.2 to i64
12  %a = getelementptr inbounds i8, ptr %mem, i64 %sext.zext.1
13  %b = getelementptr inbounds i8, ptr %mem, i64 %sext.zext.2
14  load i8, ptr %a
15  load i8, ptr %b
16  ret void
17}
18
19; CHECK-LABEL: test_zext_sext_amounts
20; CHECK: MayAlias: i8* %a, i8* %b
21; %a and %b only PartialAlias as, although they're both zext(sext(%num)) they'll extend the sign by a different
22; number of bits before zext-ing the remainder.
23define void @test_zext_sext_amounts(ptr %mem, i8 %num) {
24  %sext.1 = sext i8 %num to i16
25  %sext.zext.1 = zext i16 %sext.1 to i64
26  %sext.2 = sext i8 %num to i32
27  %sext.zext.2 = zext i32 %sext.2 to i64
28  %a = getelementptr inbounds i8, ptr %mem, i64 %sext.zext.1
29  %b = getelementptr inbounds i8, ptr %mem, i64 %sext.zext.2
30  load i8, ptr %a
31  load i8, ptr %b
32  ret void
33}
34
35; CHECK-LABEL: based_on_pr18068
36; CHECK: NoAlias: i8* %a, i8* %b
37; CHECK: NoAlias: i8* %a, i8* %c
38define void @based_on_pr18068(i32 %loaded, ptr %mem) {
39  %loaded.64 = zext i32 %loaded to i64
40  %add1 = add i32 %loaded, -1 ; unsigned wraps unless %loaded == 0
41  %add1.64 = zext i32 %add1 to i64 ; is zext(%loaded) always != zext(%loaded - 1)? Yes -> NoAlias
42  %sub1 = sub i32 %loaded, 1 ; unsigned wraps iff %loaded == 0
43  %sub1.64 = zext i32 %sub1 to i64 ; is zext(%loaded) always != zext(%loaded - 1)? Yes -> NoAlias
44  %a = getelementptr inbounds i8, ptr %mem, i64 %loaded.64
45  %b = getelementptr inbounds i8, ptr %mem, i64 %add1.64
46  %c = getelementptr inbounds i8, ptr %mem, i64 %sub1.64
47  load i8, ptr %a
48  load i8, ptr %b
49  load i8, ptr %c
50  ret void
51}
52
53; CHECK-LABEL: test_path_dependence
54; CHECK: MayAlias: i8* %a, i8* %b
55; CHECK: MustAlias: i8* %a, i8* %c
56; CHECK: MayAlias: i8* %a, i8* %d
57define void @test_path_dependence(i16 %p, ptr %mem) {
58  %p.minus1 = add i16 %p, -1 ; this will always unsigned-wrap, unless %p == 0
59  %p.minus1.64 = zext i16 %p.minus1 to i64
60  %p.64.again = add i64 %p.minus1.64, 1 ; either %p (if we wrapped) or 65536 (if we didn't)
61
62  %p.nsw.nuw.minus1 = sub nsw nuw i16 %p, 1 ; as nuw we know %p >= 1, and as nsw %p <= 32767
63  %p.nsw.nuw.minus1.64 = zext i16 %p.nsw.nuw.minus1 to i64
64  %p.nsw.nuw.64.again = add nsw nuw i64 %p.nsw.nuw.minus1.64, 1 ; ...so always exactly %p
65
66  %p.nsw.minus1 = sub nsw i16 %p, 1 ; only nsw, so can only guarantee %p != 0x1000
67  %p.nsw.minus1.64 = zext i16 %p.nsw.minus1 to i64 ; when %p > 0x1000 (ie <= 0 as a signed number) then the zext will make this a huge positive number
68  %p.nsw.64.again = add nsw i64 %p.nsw.minus1.64, 1 ; ...and so this is very much != %p
69
70  %p.64 = zext i16 %p to i64
71  %a = getelementptr inbounds i8, ptr %mem, i64 %p.64
72  %b = getelementptr inbounds i8, ptr %mem, i64 %p.64.again
73  %c = getelementptr inbounds i8, ptr %mem, i64 %p.nsw.nuw.64.again
74  %d = getelementptr inbounds i8, ptr %mem, i64 %p.nsw.64.again
75  load i8, ptr %a
76  load i8, ptr %b
77  load i8, ptr %c
78  load i8, ptr %d
79  ret void
80}
81
82; CHECK-LABEL: test_zext_sext_255
83; CHECK: NoAlias: i8* %a, i8* %b
84define void @test_zext_sext_255(ptr %mem) {
85  %zext.255 = zext i8 255 to i16 ; 0x00FF
86  %sext.255 = sext i8 255 to i16 ; 0xFFFF
87  %zext.sext.255 = zext i16 %sext.255 to i32 ; 0x0000FFFF
88  %sext.zext.255 = sext i16 %zext.255 to i32 ; 0x000000FF
89  %zext.zext.sext.255 = zext i32 %zext.sext.255 to i64
90  %zext.sext.zext.255 = zext i32 %sext.zext.255 to i64
91  %a = getelementptr inbounds i8, ptr %mem, i64 %zext.zext.sext.255
92  %b = getelementptr inbounds i8, ptr %mem, i64 %zext.sext.zext.255
93  load i8, ptr %a
94  load i8, ptr %b
95  ret void
96}
97
98; CHECK-LABEL: test_zext_sext_num
99; CHECK: MayAlias: i8* %a, i8* %b
100; %a and %b NoAlias if %num == 255 (see @test_zext_sext_255), but %a and %b NoAlias for other values of %num (e.g. 0)
101define void @test_zext_sext_num(ptr %mem, i8 %num) {
102  %zext.num = zext i8 %num to i16
103  %sext.num = sext i8 %num to i16
104  %zext.sext.num = zext i16 %sext.num to i32
105  %sext.zext.num = sext i16 %zext.num to i32
106  %zext.zext.sext.num = zext i32 %zext.sext.num to i64
107  %zext.sext.zext.num = zext i32 %sext.zext.num to i64
108  %a = getelementptr inbounds i8, ptr %mem, i64 %zext.zext.sext.num
109  %b = getelementptr inbounds i8, ptr %mem, i64 %zext.sext.zext.num
110  load i8, ptr %a
111  load i8, ptr %b
112  ret void
113}
114
115; CHECK-LABEL: uncompressStream
116; CHECK: MustAlias:  i8* %a, i8* %b
117; CHECK: NoAlias:  i8* %a, i8* %c
118define void @uncompressStream(ptr %mem) {
119  %zext.255 = zext i8 255 to i32
120  %sext.255 = sext i8 255 to i32
121  %a = getelementptr inbounds i8, ptr %mem, i32 255
122  %b = getelementptr inbounds i8, ptr %mem, i32 %zext.255
123  %c = getelementptr inbounds i8, ptr %mem, i32 %sext.255
124  load i8, ptr %a
125  load i8, ptr %b
126  load i8, ptr %c
127  ret void
128}
129
130; CHECK-LABEL: constantOffsetHeuristic_i3_i32
131; CHECK: NoAlias:  i32* %a, i32* %b
132; CHECK: NoAlias:  i32* %a, i32* %c
133; CHECK: NoAlias:  i32* %b, i32* %c
134define void @constantOffsetHeuristic_i3_i32(ptr %mem, i3 %val) {
135  %zext.plus.7 = add nsw i3 %val, 7
136  %zext.plus.4 = add nsw i3 %val, 4
137  %zext.val = zext i3 %val to i32
138  %zext.4 = zext i3 %zext.plus.4 to i32
139  %zext.7 = zext i3 %zext.plus.7 to i32
140  %a = getelementptr inbounds i32, ptr %mem, i32 %zext.4
141  %b = getelementptr inbounds i32, ptr %mem, i32 %zext.7
142  %c = getelementptr inbounds i32, ptr %mem, i32 %zext.val
143  load i32, ptr %a
144  load i32, ptr %b
145  load i32, ptr %c
146  ret void
147}
148
149; CHECK-LABEL: constantOffsetHeuristic_i8_i32
150; CHECK: NoAlias:  i32* %a, i32* %b
151; CHECK: NoAlias:  i32* %a, i32* %c
152; CHECK: NoAlias:  i32* %b, i32* %c
153define void @constantOffsetHeuristic_i8_i32(ptr %mem, i8 %val) {
154  %zext.plus.7 = add nsw i8 %val, 7
155  %zext.plus.4 = add nsw i8 %val, 4
156  %zext.val = zext i8 %val to i32
157  %zext.4 = zext i8 %zext.plus.4 to i32
158  %zext.7 = zext i8 %zext.plus.7 to i32
159  %a = getelementptr inbounds i32, ptr %mem, i32 %zext.4
160  %b = getelementptr inbounds i32, ptr %mem, i32 %zext.7
161  %c = getelementptr inbounds i32, ptr %mem, i32 %zext.val
162  load i32, ptr %a
163  load i32, ptr %b
164  load i32, ptr %c
165  ret void
166}
167
168; CHECK-LABEL: constantOffsetHeuristic_i3_i8
169; CHECK: MayAlias:  i32* %a.8, i32* %b.8
170; CHECK: NoAlias:  i32* %a.8, i32* %c.8
171; CHECK: MayAlias:  i32* %b.8, i32* %c.8
172define void @constantOffsetHeuristic_i3_i8(ptr %mem, i3 %val) {
173  %zext.plus.7 = add nsw i3 %val, 7
174  %zext.plus.4 = add nsw i3 %val, 4
175  %zext.val = zext i3 %val to i32
176  %zext.4 = zext i3 %zext.plus.4 to i32
177  %zext.7 = zext i3 %zext.plus.7 to i32
178  %a.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.4
179  %b.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.7
180  %c.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.val
181  load i32, ptr %a.8
182  load i32, ptr %b.8
183  load i32, ptr %c.8
184  ret void
185}
186
187; CHECK-LABEL: constantOffsetHeuristic_i8_i8
188; CHECK: MayAlias:  i32* %a.8, i32* %b.8
189; CHECK: NoAlias:  i32* %a.8, i32* %c.8
190; CHECK: NoAlias:  i32* %b.8, i32* %c.8
191define void @constantOffsetHeuristic_i8_i8(ptr %mem, i8 %val) {
192  %zext.plus.7 = add nsw i8 %val, 7
193  %zext.plus.4 = add nsw i8 %val, 4
194  %zext.val = zext i8 %val to i32
195  %zext.4 = zext i8 %zext.plus.4 to i32
196  %zext.7 = zext i8 %zext.plus.7 to i32
197  %a.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.4
198  %b.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.7
199  %c.8 = getelementptr inbounds i8, ptr %mem, i32 %zext.val
200  load i32, ptr %a.8
201  load i32, ptr %b.8
202  load i32, ptr %c.8
203  ret void
204}
205
206; CHECK-LABEL: different_large_bitwidths
207; MayAlias: ptr %p1, ptr %p2
208define void @different_large_bitwidths(ptr %a, i64 %i, i128 %j) {
209  %p1 = getelementptr i8, ptr %a, i64 %i
210  %p2 = getelementptr i8, ptr %a, i128 %j
211  load i8, ptr %p1
212  load i8, ptr %p2
213  ret void
214}
215