1; RUN: opt < %s -basic-aa -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: %struct* %y_12, i32* %x
19; CHECK-DAG: MayAlias: i32* %x, i80* %y_10
20
21; CHECK-DAG: MayAlias: %struct* %st, i64* %y_8
22; CHECK-DAG: MayAlias: i32* %z, i64* %y_8
23; CHECK-DAG: NoAlias: i32* %x, i64* %y_8
24
25; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y
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  ret void
37}
38
39; As the GEP is not inbounds, these pointers may alias due to overflow.
40; CHECK-LABEL: test_not_inbounds
41; CHECK: MayAlias: i32* %x, i32* %y
42define void @test_not_inbounds(%struct* %st, i64 %i, i64 %j, i64 %k) {
43  %x = getelementptr %struct, %struct* %st, i64 %i, i32 0
44  %y = getelementptr %struct, %struct* %st, i64 %j, i32 1
45  ret void
46}
47
48; CHECK-LABEL: test_in_array
49
50; CHECK-DAG: MayAlias: [1 x %struct]* %st, i32* %x
51; CHECK-DAG: MayAlias: [1 x %struct]* %st, i32* %y
52; CHECK-DAG: MayAlias: [1 x %struct]* %st, i32* %z
53
54; CHECK-DAG: NoAlias: i32* %x, i32* %y
55; CHECK-DAG: NoAlias: i32* %x, i32* %z
56; CHECK-DAG: NoAlias: i32* %y, i32* %z
57
58; CHECK-DAG: MayAlias: %struct* %y_12, [1 x %struct]* %st
59; CHECK-DAG: MayAlias: %struct* %y_12, i32* %x
60; CHECK-DAG: MayAlias: i32* %x, i80* %y_10
61
62; CHECK-DAG: MayAlias: [1 x %struct]* %st, i64* %y_8
63; CHECK-DAG: MayAlias: i32* %z, i64* %y_8
64; CHECK-DAG: NoAlias: i32* %x, i64* %y_8
65
66; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y
67; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
68; CHECK-DAG: MustAlias: i32* %y, i80* %y_10
69
70define void @test_in_array([1 x %struct]* %st, i64 %i, i64 %j, i64 %k, i64 %i1, i64 %j1, i64 %k1) {
71  %x = getelementptr inbounds [1 x %struct], [1 x %struct]* %st, i64 %i, i64 %i1, i32 0
72  %y = getelementptr inbounds [1 x %struct], [1 x %struct]* %st, i64 %j, i64 %j1, i32 1
73  %z = getelementptr inbounds [1 x %struct], [1 x %struct]* %st, i64 %k, i64 %k1, i32 2
74  %y_12 = bitcast i32* %y to %struct*
75  %y_10 = bitcast i32* %y to i80*
76  %y_8 = bitcast i32* %y to i64*
77  ret void
78}
79
80; CHECK-LABEL: test_in_3d_array
81
82; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i32* %x
83; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i32* %y
84; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i32* %z
85
86; CHECK-DAG: NoAlias: i32* %x, i32* %y
87; CHECK-DAG: NoAlias: i32* %x, i32* %z
88; CHECK-DAG: NoAlias: i32* %y, i32* %z
89
90; CHECK-DAG: MayAlias: %struct* %y_12, [1 x [1 x [1 x %struct]]]* %st
91; CHECK-DAG: MayAlias: %struct* %y_12, i32* %x
92; CHECK-DAG: MayAlias: i32* %x, i80* %y_10
93
94; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i64* %y_8
95; CHECK-DAG: MayAlias: i32* %z, i64* %y_8
96; CHECK-DAG: NoAlias: i32* %x, i64* %y_8
97
98; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y
99; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
100; CHECK-DAG: MustAlias: i32* %y, i80* %y_10
101
102define 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) {
103  %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
104  %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
105  %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
106  %y_12 = bitcast i32* %y to %struct*
107  %y_10 = bitcast i32* %y to i80*
108  %y_8 = bitcast i32* %y to i64*
109  ret void
110}
111
112; CHECK-LABEL: test_same_underlying_object_same_indices
113
114; CHECK-DAG: NoAlias: i32* %x, i32* %x2
115; CHECK-DAG: NoAlias: i32* %y, i32* %y2
116; CHECK-DAG: NoAlias: i32* %z, i32* %z2
117
118; CHECK-DAG: NoAlias: i32* %x, i32* %y2
119; CHECK-DAG: NoAlias: i32* %x, i32* %z2
120
121; CHECK-DAG: NoAlias: i32* %x2, i32* %y
122; CHECK-DAG: NoAlias: i32* %y, i32* %z2
123
124; CHECK-DAG: NoAlias: i32* %x2, i32* %z
125; CHECK-DAG: NoAlias: i32* %y2, i32* %z
126
127define void @test_same_underlying_object_same_indices(%struct* %st, i64 %i, i64 %j, i64 %k) {
128  %st2 = getelementptr inbounds %struct, %struct* %st, i32 10
129  %x2 = getelementptr inbounds %struct, %struct* %st2, i64 %i, i32 0
130  %y2 = getelementptr inbounds %struct, %struct* %st2, i64 %j, i32 1
131  %z2 = getelementptr inbounds %struct, %struct* %st2, i64 %k, i32 2
132  %x = getelementptr inbounds %struct, %struct* %st, i64 %i, i32 0
133  %y = getelementptr inbounds %struct, %struct* %st, i64 %j, i32 1
134  %z = getelementptr inbounds %struct, %struct* %st, i64 %k, i32 2
135  ret void
136}
137
138; CHECK-LABEL: test_same_underlying_object_different_indices
139
140; CHECK-DAG: MayAlias: i32* %x, i32* %x2
141; CHECK-DAG: MayAlias: i32* %y, i32* %y2
142; CHECK-DAG: MayAlias: i32* %z, i32* %z2
143
144; CHECK-DAG: NoAlias: i32* %x, i32* %y2
145; CHECK-DAG: NoAlias: i32* %x, i32* %z2
146
147; CHECK-DAG: NoAlias: i32* %x2, i32* %y
148; CHECK-DAG: NoAlias: i32* %y, i32* %z2
149
150; CHECK-DAG: NoAlias: i32* %x2, i32* %z
151; CHECK-DAG: NoAlias: i32* %y2, i32* %z
152
153define void @test_same_underlying_object_different_indices(%struct* %st, i64 %i1, i64 %j1, i64 %k1, i64 %i2, i64 %k2, i64 %j2) {
154  %st2 = getelementptr inbounds %struct, %struct* %st, i32 10
155  %x2 = getelementptr inbounds %struct, %struct* %st2, i64 %i2, i32 0
156  %y2 = getelementptr inbounds %struct, %struct* %st2, i64 %j2, i32 1
157  %z2 = getelementptr inbounds %struct, %struct* %st2, i64 %k2, i32 2
158  %x = getelementptr inbounds %struct, %struct* %st, i64 %i1, i32 0
159  %y = getelementptr inbounds %struct, %struct* %st, i64 %j1, i32 1
160  %z = getelementptr inbounds %struct, %struct* %st, i64 %k1, i32 2
161  ret void
162}
163
164
165%struct2 = type { [1 x { i32, i32 }], [2 x { i32 }] }
166
167; CHECK-LABEL: test_struct_in_array
168; CHECK-DAG: MustAlias: i32* %x, i32* %y
169define void @test_struct_in_array(%struct2* %st, i64 %i, i64 %j, i64 %k) {
170  %x = getelementptr inbounds %struct2, %struct2* %st, i32 0, i32 1, i32 1, i32 0
171  %y = getelementptr inbounds %struct2, %struct2* %st, i32 0, i32 0, i32 1, i32 1
172  ret void
173}
174
175; PR27418 - Treat GEP indices with the same value but different types the same
176; CHECK-LABEL: test_different_index_types
177; CHECK: MustAlias: i16* %tmp1, i16* %tmp2
178define void @test_different_index_types([2 x i16]* %arr) {
179  %tmp1 = getelementptr inbounds [2 x i16], [2 x i16]* %arr, i16 0, i32 1
180  %tmp2 = getelementptr inbounds [2 x i16], [2 x i16]* %arr, i16 0, i16 1
181  ret void
182}
183