1; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
2
3target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4
5%struct = type { i32, i32, i32 }
6
7; CHECK-LABEL: test_simple
8
9; CHECK-DAG: MayAlias: %struct* %st, i32* %x
10; CHECK-DAG: MayAlias: %struct* %st, i32* %y
11; CHECK-DAG: MayAlias: %struct* %st, i32* %z
12
13; CHECK-DAG: NoAlias: i32* %x, i32* %y
14; CHECK-DAG: NoAlias: i32* %x, i32* %z
15; CHECK-DAG: NoAlias: i32* %y, i32* %z
16
17; CHECK-DAG: MayAlias: %struct* %st, %struct* %y_12
18; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12
19; CHECK-DAG: MayAlias: i32* %x, i80* %y_10
20
21; CHECK-DAG: MayAlias: %struct* %st, i64* %y_8
22; CHECK-DAG: MayAlias: i64* %y_8, i32* %z
23; CHECK-DAG: NoAlias: i32* %x, i64* %y_8
24
25; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12
26; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
27; CHECK-DAG: MustAlias: i32* %y, i80* %y_10
28
29define void @test_simple(%struct* %st, i64 %i, i64 %j, i64 %k) {
30  %x = getelementptr inbounds %struct, %struct* %st, i64 %i, i32 0
31  %y = getelementptr inbounds %struct, %struct* %st, i64 %j, i32 1
32  %z = getelementptr inbounds %struct, %struct* %st, i64 %k, i32 2
33  %y_12 = bitcast i32* %y to %struct*
34  %y_10 = bitcast i32* %y to i80*
35  %y_8 = bitcast i32* %y to i64*
36  load %struct, %struct* %st
37  load i32, i32* %x
38  load i32, i32* %y
39  load i32, i32* %z
40  load %struct, %struct* %y_12
41  load i80, i80* %y_10
42  load i64, i64* %y_8
43  ret void
44}
45
46; As the GEP is not inbounds, these pointers may alias due to overflow.
47; CHECK-LABEL: test_not_inbounds
48; CHECK: MayAlias: i32* %x, i32* %y
49define void @test_not_inbounds(%struct* %st, i64 %i, i64 %j, i64 %k) {
50  %x = getelementptr %struct, %struct* %st, i64 %i, i32 0
51  %y = getelementptr %struct, %struct* %st, i64 %j, i32 1
52  load i32, i32* %x
53  load i32, i32* %y
54  ret void
55}
56
57; CHECK-LABEL: test_in_array
58
59; CHECK-DAG: MayAlias: [1 x %struct]* %st, i32* %x
60; CHECK-DAG: MayAlias: [1 x %struct]* %st, i32* %y
61; CHECK-DAG: MayAlias: [1 x %struct]* %st, i32* %z
62
63; CHECK-DAG: NoAlias: i32* %x, i32* %y
64; CHECK-DAG: NoAlias: i32* %x, i32* %z
65; CHECK-DAG: NoAlias: i32* %y, i32* %z
66
67; CHECK-DAG: MayAlias: [1 x %struct]* %st, %struct* %y_12
68; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12
69; CHECK-DAG: MayAlias: i32* %x, i80* %y_10
70
71; CHECK-DAG: MayAlias: [1 x %struct]* %st, i64* %y_8
72; CHECK-DAG: MayAlias: i64* %y_8, i32* %z
73; CHECK-DAG: NoAlias: i32* %x, i64* %y_8
74
75; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12
76; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
77; CHECK-DAG: MustAlias: i32* %y, i80* %y_10
78
79define void @test_in_array([1 x %struct]* %st, i64 %i, i64 %j, i64 %k, i64 %i1, i64 %j1, i64 %k1) {
80  %x = getelementptr inbounds [1 x %struct], [1 x %struct]* %st, i64 %i, i64 %i1, i32 0
81  %y = getelementptr inbounds [1 x %struct], [1 x %struct]* %st, i64 %j, i64 %j1, i32 1
82  %z = getelementptr inbounds [1 x %struct], [1 x %struct]* %st, i64 %k, i64 %k1, i32 2
83  %y_12 = bitcast i32* %y to %struct*
84  %y_10 = bitcast i32* %y to i80*
85  %y_8 = bitcast i32* %y to i64*
86  load [1 x %struct], [1 x %struct]* %st
87  load i32, i32* %x
88  load i32, i32* %y
89  load i32, i32* %z
90  load %struct, %struct* %y_12
91  load i80, i80* %y_10
92  load i64, i64* %y_8
93  ret void
94}
95
96; CHECK-LABEL: test_in_3d_array
97
98; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i32* %x
99; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i32* %y
100; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i32* %z
101
102; CHECK-DAG: NoAlias: i32* %x, i32* %y
103; CHECK-DAG: NoAlias: i32* %x, i32* %z
104; CHECK-DAG: NoAlias: i32* %y, i32* %z
105
106; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, %struct* %y_12
107; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12
108; CHECK-DAG: MayAlias: i32* %x, i80* %y_10
109
110; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i64* %y_8
111; CHECK-DAG: MayAlias: i64* %y_8, i32* %z
112; CHECK-DAG: NoAlias: i32* %x, i64* %y_8
113
114; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12
115; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
116; CHECK-DAG: MustAlias: i32* %y, i80* %y_10
117
118define void @test_in_3d_array([1 x [1 x [1 x %struct]]]* %st, i64 %i, i64 %j, i64 %k, i64 %i1, i64 %j1, i64 %k1, i64 %i2, i64 %j2, i64 %k2, i64 %i3, i64 %j3, i64 %k3) {
119  %x = getelementptr inbounds [1 x [1 x [1 x %struct]]], [1 x [1 x [1 x %struct]]]* %st, i64 %i, i64 %i1, i64 %i2, i64 %i3, i32 0
120  %y = getelementptr inbounds [1 x [1 x [1 x %struct]]], [1 x [1 x [1 x %struct]]]* %st, i64 %j, i64 %j1, i64 %j2, i64 %j3, i32 1
121  %z = getelementptr inbounds [1 x [1 x [1 x %struct]]], [1 x [1 x [1 x %struct]]]* %st, i64 %k, i64 %k1, i64 %k2, i64 %k3, i32 2
122  %y_12 = bitcast i32* %y to %struct*
123  %y_10 = bitcast i32* %y to i80*
124  %y_8 = bitcast i32* %y to i64*
125  load [1 x [1 x [1 x %struct]]], [1 x [1 x [1 x %struct]]]* %st
126  load i32, i32* %x
127  load i32, i32* %y
128  load i32, i32* %z
129  load %struct, %struct* %y_12
130  load i80, i80* %y_10
131  load i64, i64* %y_8
132  ret void
133}
134
135; CHECK-LABEL: test_same_underlying_object_same_indices
136
137; CHECK-DAG: NoAlias: i32* %x, i32* %x2
138; CHECK-DAG: NoAlias: i32* %y, i32* %y2
139; CHECK-DAG: NoAlias: i32* %z, i32* %z2
140
141; CHECK-DAG: NoAlias: i32* %x, i32* %y2
142; CHECK-DAG: NoAlias: i32* %x, i32* %z2
143
144; CHECK-DAG: NoAlias: i32* %x2, i32* %y
145; CHECK-DAG: NoAlias: i32* %y, i32* %z2
146
147; CHECK-DAG: NoAlias: i32* %x2, i32* %z
148; CHECK-DAG: NoAlias: i32* %y2, i32* %z
149
150define void @test_same_underlying_object_same_indices(%struct* %st, i64 %i, i64 %j, i64 %k) {
151  %st2 = getelementptr inbounds %struct, %struct* %st, i32 10
152  %x2 = getelementptr inbounds %struct, %struct* %st2, i64 %i, i32 0
153  %y2 = getelementptr inbounds %struct, %struct* %st2, i64 %j, i32 1
154  %z2 = getelementptr inbounds %struct, %struct* %st2, i64 %k, i32 2
155  %x = getelementptr inbounds %struct, %struct* %st, i64 %i, i32 0
156  %y = getelementptr inbounds %struct, %struct* %st, i64 %j, i32 1
157  %z = getelementptr inbounds %struct, %struct* %st, i64 %k, i32 2
158  load i32, i32* %x
159  load i32, i32* %y
160  load i32, i32* %z
161  load i32, i32* %x2
162  load i32, i32* %y2
163  load i32, i32* %z2
164  ret void
165}
166
167; CHECK-LABEL: test_same_underlying_object_different_indices
168
169; CHECK-DAG: MayAlias: i32* %x, i32* %x2
170; CHECK-DAG: MayAlias: i32* %y, i32* %y2
171; CHECK-DAG: MayAlias: i32* %z, i32* %z2
172
173; CHECK-DAG: NoAlias: i32* %x, i32* %y2
174; CHECK-DAG: NoAlias: i32* %x, i32* %z2
175
176; CHECK-DAG: NoAlias: i32* %x2, i32* %y
177; CHECK-DAG: NoAlias: i32* %y, i32* %z2
178
179; CHECK-DAG: NoAlias: i32* %x2, i32* %z
180; CHECK-DAG: NoAlias: i32* %y2, i32* %z
181
182define void @test_same_underlying_object_different_indices(%struct* %st, i64 %i1, i64 %j1, i64 %k1, i64 %i2, i64 %k2, i64 %j2) {
183  %st2 = getelementptr inbounds %struct, %struct* %st, i32 10
184  %x2 = getelementptr inbounds %struct, %struct* %st2, i64 %i2, i32 0
185  %y2 = getelementptr inbounds %struct, %struct* %st2, i64 %j2, i32 1
186  %z2 = getelementptr inbounds %struct, %struct* %st2, i64 %k2, i32 2
187  %x = getelementptr inbounds %struct, %struct* %st, i64 %i1, i32 0
188  %y = getelementptr inbounds %struct, %struct* %st, i64 %j1, i32 1
189  %z = getelementptr inbounds %struct, %struct* %st, i64 %k1, i32 2
190  load i32, i32* %x
191  load i32, i32* %y
192  load i32, i32* %z
193  load i32, i32* %x2
194  load i32, i32* %y2
195  load i32, i32* %z2
196  ret void
197}
198
199
200%struct2 = type { [1 x { i32, i32 }], [2 x { i32 }] }
201
202; CHECK-LABEL: test_struct_in_array
203; CHECK-DAG: MustAlias: i32* %x, i32* %y
204define void @test_struct_in_array(%struct2* %st, i64 %i, i64 %j, i64 %k) {
205  %x = getelementptr inbounds %struct2, %struct2* %st, i32 0, i32 1, i32 1, i32 0
206  %y = getelementptr inbounds %struct2, %struct2* %st, i32 0, i32 0, i32 1, i32 1
207  load i32, i32* %x
208  load i32, i32* %y
209  ret void
210}
211
212; PR27418 - Treat GEP indices with the same value but different types the same
213; CHECK-LABEL: test_different_index_types
214; CHECK: MustAlias: i16* %tmp1, i16* %tmp2
215define void @test_different_index_types([2 x i16]* %arr) {
216  %tmp1 = getelementptr inbounds [2 x i16], [2 x i16]* %arr, i16 0, i32 1
217  %tmp2 = getelementptr inbounds [2 x i16], [2 x i16]* %arr, i16 0, i16 1
218  load i16, i16* %tmp1
219  load i16, i16* %tmp2
220  ret void
221}
222