[AMDGPU] Parse wwm filter flag for regalloc fast (#119347)
[llvm-project.git] / llvm / test / Transforms / Attributor / multiple-offsets-pointer-info.ll
blobf04ac4d73340fa4112182f97ee3b75e18384c959
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
5 %struct.T = type { i32, [10 x [20 x i8]] }
7 declare noalias ptr @calloc(i64, i64) allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc"
9 define i8 @select_offsets_simplifiable_1(i1 %cnd1, i1 %cnd2) {
10 ; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_1
11 ; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) {
12 ; CHECK-NEXT:  entry:
13 ; CHECK-NEXT:    [[BYTES:%.*]] = call ptr @calloc(i64 noundef 1024, i64 noundef 1)
14 ; CHECK-NEXT:    [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
15 ; CHECK-NEXT:    store i8 23, ptr [[GEP23]], align 4
16 ; CHECK-NEXT:    [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 29
17 ; CHECK-NEXT:    store i8 29, ptr [[GEP29]], align 4
18 ; CHECK-NEXT:    [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 7
19 ; CHECK-NEXT:    store i8 7, ptr [[GEP7]], align 4
20 ; CHECK-NEXT:    [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 31
21 ; CHECK-NEXT:    [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
22 ; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7
23 ; CHECK-NEXT:    [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]
24 ; CHECK-NEXT:    [[I:%.*]] = load i8, ptr [[GEP_SEL]], align 4
25 ; CHECK-NEXT:    ret i8 [[I]]
27 entry:
28   %Bytes = call ptr @calloc(i64 1024, i64 1)
30   %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23
31   store i8 23, ptr %gep23, align 4
32   %gep29 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 29
33   store i8 29, ptr %gep29, align 4
34   %gep7 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 7
35   store i8 7, ptr %gep7, align 4
37   ;; This store is redundant, hence removed.
38   %gep31 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 31
39   store i8 42, ptr %gep31, align 4
41   %sel0 = select i1 %cnd1, i64 23, i64 29
42   %sel1 = select i1 %cnd2, i64 %sel0, i64 7
43   %gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1
44   %i = load i8, ptr %gep.sel, align 4
45   ret i8 %i
48 define i8 @select_offsets_simplifiable_2(i1 %cnd1, i1 %cnd2) {
49 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
50 ; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_2
51 ; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1:[0-9]+]] {
52 ; CHECK-NEXT:  entry:
53 ; CHECK-NEXT:    [[BYTES:%.*]] = alloca [1024 x i8], align 16
54 ; CHECK-NEXT:    [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
55 ; CHECK-NEXT:    store i8 23, ptr [[GEP23]], align 4
56 ; CHECK-NEXT:    [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 29
57 ; CHECK-NEXT:    store i8 29, ptr [[GEP29]], align 4
58 ; CHECK-NEXT:    [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 7
59 ; CHECK-NEXT:    store i8 7, ptr [[GEP7]], align 4
60 ; CHECK-NEXT:    [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 31
61 ; CHECK-NEXT:    [[SEL0:%.*]] = select i1 [[CND1]], i64 20, i64 26
62 ; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 4
63 ; CHECK-NEXT:    [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]
64 ; CHECK-NEXT:    [[GEP_PLUS:%.*]] = getelementptr inbounds i8, ptr [[GEP_SEL]], i64 3
65 ; CHECK-NEXT:    [[I:%.*]] = load i8, ptr [[GEP_PLUS]], align 4
66 ; CHECK-NEXT:    ret i8 [[I]]
68 entry:
69   %Bytes = alloca [1024 x i8], align 16
71   %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23
72   store i8 23, ptr %gep23, align 4
73   %gep29 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 29
74   store i8 29, ptr %gep29, align 4
75   %gep7 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 7
76   store i8 7, ptr %gep7, align 4
78   ;; This store is redundant, hence removed.
79   %gep31 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 31
80   store i8 42, ptr %gep31, align 4
82   ;; Adjust the offsets so that they match the stores after adding 3
83   %sel0 = select i1 %cnd1, i64 20, i64 26
84   %sel1 = select i1 %cnd2, i64 %sel0, i64 4
85   %gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1
86   %gep.plus = getelementptr inbounds i8, ptr %gep.sel, i64 3
87   %i = load i8, ptr %gep.plus, align 4
88   ret i8 %i
91 define i8 @select_offsets_simplifiable_3(i1 %cnd1, i1 %cnd2) {
92 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
93 ; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_3
94 ; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
95 ; CHECK-NEXT:  entry:
96 ; CHECK-NEXT:    [[BUNDLE:%.*]] = alloca [[STRUCT_T:%.*]], align 64
97 ; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CND1]], i64 1, i64 3
98 ; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[CND2]], i64 5, i64 11
99 ; CHECK-NEXT:    [[GEP_SEL:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[BUNDLE]], i64 0, i32 1, i64 [[SEL1]], i64 [[SEL2]]
100 ; CHECK-NEXT:    ret i8 100
102 entry:
103   %bundle = alloca %struct.T, align 64
104   %gep.fixed = getelementptr inbounds %struct.T, ptr %bundle, i64 0, i32 1, i64 1, i64 1
105   store i8 100, ptr %gep.fixed, align 4
106   %sel1 = select i1 %cnd1, i64 1, i64 3
107   %sel2 = select i1 %cnd2, i64 5, i64 11
108   %gep.sel = getelementptr inbounds %struct.T, ptr %bundle, i64 0, i32 1, i64 %sel1, i64 %sel2
109   store i8 42, ptr %gep.sel, align 4
110   %i = load i8, ptr %gep.fixed, align 4
111   ret i8 %i
114 ; Similar to select_offsets_not_simplifiable_3 but with uninitialized memory.
115 define i8 @select_offsets_simplifiable_4(i1 %cnd1, i1 %cnd2) {
116 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
117 ; CHECK-LABEL: define {{[^@]+}}@select_offsets_simplifiable_4
118 ; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
119 ; CHECK-NEXT:  entry:
120 ; CHECK-NEXT:    [[BYTES:%.*]] = alloca [1024 x i8], align 16
121 ; CHECK-NEXT:    [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
122 ; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7
123 ; CHECK-NEXT:    [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]
124 ; CHECK-NEXT:    ret i8 100
126 entry:
127   %Bytes = alloca [1024 x i8], align 16
128   %sel0 = select i1 %cnd1, i64 23, i64 29
129   %sel1 = select i1 %cnd2, i64 %sel0, i64 7
130   %gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1
131   store i8 100, ptr %gep.sel, align 4
132   %gep29 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 29
133   %i = load i8, ptr %gep29, align 4
134   ret i8 %i
137 define i8 @select_offsets_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {
138 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
139 ; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_1
140 ; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
141 ; CHECK-NEXT:  entry:
142 ; CHECK-NEXT:    [[BYTES:%.*]] = alloca [1024 x i8], align 16
143 ; CHECK-NEXT:    [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
144 ; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7
145 ; CHECK-NEXT:    [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
146 ; CHECK-NEXT:    store i8 100, ptr [[GEP23]], align 4
147 ; CHECK-NEXT:    [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]
148 ; CHECK-NEXT:    [[I:%.*]] = load i8, ptr [[GEP_SEL]], align 4
149 ; CHECK-NEXT:    ret i8 [[I]]
151 entry:
152   %Bytes = alloca [1024 x i8], align 16
153   %sel0 = select i1 %cnd1, i64 23, i64 29
154   %sel1 = select i1 %cnd2, i64 %sel0, i64 7
155   %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23
156   store i8 100, ptr %gep23, align 4
157   %gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1
158   %i = load i8, ptr %gep.sel, align 4
159   ret i8 %i
162 define i8 @select_offsets_not_simplifiable_2(i1 %cnd1, i1 %cnd2) {
163 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
164 ; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_2
165 ; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
166 ; CHECK-NEXT:  entry:
167 ; CHECK-NEXT:    [[BYTES:%.*]] = alloca [1024 x i8], align 16
168 ; CHECK-NEXT:    [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
169 ; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7
170 ; CHECK-NEXT:    [[GEP32:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 32
171 ; CHECK-NEXT:    store i8 100, ptr [[GEP32]], align 16
172 ; CHECK-NEXT:    [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]
173 ; CHECK-NEXT:    [[GEP_PLUS:%.*]] = getelementptr inbounds i8, ptr [[GEP_SEL]], i64 3
174 ; CHECK-NEXT:    [[I:%.*]] = load i8, ptr [[GEP_PLUS]], align 4
175 ; CHECK-NEXT:    ret i8 [[I]]
177 entry:
178   %Bytes = alloca [1024 x i8], align 16
179   %sel0 = select i1 %cnd1, i64 23, i64 29
180   %sel1 = select i1 %cnd2, i64 %sel0, i64 7
181   %gep32 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 32
182   store i8 100, ptr %gep32, align 4
183   %gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1
184   %gep.plus = getelementptr inbounds i8, ptr %gep.sel, i64 3
185   %i = load i8, ptr %gep.plus, align 4
186   ret i8 %i
189 define i8 @select_offsets_not_simplifiable_3(i1 %cnd1, i1 %cnd2) {
190 ; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_3
191 ; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) {
192 ; CHECK-NEXT:  entry:
193 ; CHECK-NEXT:    [[BYTES:%.*]] = call ptr @calloc(i64 noundef 1024, i64 noundef 1)
194 ; CHECK-NEXT:    [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
195 ; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7
196 ; CHECK-NEXT:    [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]
197 ; CHECK-NEXT:    store i8 100, ptr [[GEP_SEL]], align 4
198 ; CHECK-NEXT:    [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 29
199 ; CHECK-NEXT:    [[I:%.*]] = load i8, ptr [[GEP29]], align 4
200 ; CHECK-NEXT:    ret i8 [[I]]
202 entry:
203   %Bytes = call ptr @calloc(i64 1024, i64 1)
204   %sel0 = select i1 %cnd1, i64 23, i64 29
205   %sel1 = select i1 %cnd2, i64 %sel0, i64 7
206   %gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1
207   store i8 100, ptr %gep.sel, align 4
208   %gep29 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 29
209   %i = load i8, ptr %gep29, align 4
210   ret i8 %i
213 define i8 @select_offsets_not_simplifiable_4(i1 %cnd1, i1 %cnd2) {
214 ; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_4
215 ; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) {
216 ; CHECK-NEXT:  entry:
217 ; CHECK-NEXT:    [[BYTES:%.*]] = call ptr @calloc(i64 noundef 1024, i64 noundef 1)
218 ; CHECK-NEXT:    [[SEL0:%.*]] = select i1 [[CND1]], i64 23, i64 29
219 ; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CND2]], i64 [[SEL0]], i64 7
220 ; CHECK-NEXT:    [[GEP_SEL:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[SEL1]]
221 ; CHECK-NEXT:    [[GEP_PLUS:%.*]] = getelementptr inbounds i8, ptr [[GEP_SEL]], i64 3
222 ; CHECK-NEXT:    store i8 100, ptr [[GEP_PLUS]], align 4
223 ; CHECK-NEXT:    [[GEP32:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 32
224 ; CHECK-NEXT:    [[I:%.*]] = load i8, ptr [[GEP32]], align 4
225 ; CHECK-NEXT:    ret i8 [[I]]
227 entry:
228   %Bytes = call ptr @calloc(i64 1024, i64 1)
229   %sel0 = select i1 %cnd1, i64 23, i64 29
230   %sel1 = select i1 %cnd2, i64 %sel0, i64 7
231   %gep.sel = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %sel1
232   %gep.plus = getelementptr inbounds i8, ptr %gep.sel, i64 3
233   store i8 100, ptr %gep.plus, align 4
234   %gep32 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 32
235   %i = load i8, ptr %gep32, align 4
236   ret i8 %i
239 define i8 @select_offsets_not_simplifiable_5(i1 %cnd1, i1 %cnd2) {
240 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
241 ; CHECK-LABEL: define {{[^@]+}}@select_offsets_not_simplifiable_5
242 ; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
243 ; CHECK-NEXT:  entry:
244 ; CHECK-NEXT:    [[BUNDLE:%.*]] = alloca [[STRUCT_T:%.*]], align 64
245 ; CHECK-NEXT:    [[GEP_FIXED:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[BUNDLE]], i64 0, i32 1, i64 3, i64 5
246 ; CHECK-NEXT:    store i8 100, ptr [[GEP_FIXED]], align 4
247 ; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CND1]], i64 1, i64 3
248 ; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[CND2]], i64 5, i64 11
249 ; CHECK-NEXT:    [[GEP_SEL:%.*]] = getelementptr inbounds [[STRUCT_T]], ptr [[BUNDLE]], i64 0, i32 1, i64 [[SEL1]], i64 [[SEL2]]
250 ; CHECK-NEXT:    store i8 42, ptr [[GEP_SEL]], align 4
251 ; CHECK-NEXT:    [[I:%.*]] = load i8, ptr [[GEP_FIXED]], align 4
252 ; CHECK-NEXT:    ret i8 [[I]]
254 entry:
255   %bundle = alloca %struct.T, align 64
256   %gep.fixed = getelementptr inbounds %struct.T, ptr %bundle, i64 0, i32 1, i64 3, i64 5
257   store i8 100, ptr %gep.fixed, align 4
258   %sel1 = select i1 %cnd1, i64 1, i64 3
259   %sel2 = select i1 %cnd2, i64 5, i64 11
260   %gep.sel = getelementptr inbounds %struct.T, ptr %bundle, i64 0, i32 1, i64 %sel1, i64 %sel2
262   ;; This store prevents the constant 100 from being propagated to ret
263   store i8 42, ptr %gep.sel, align 4
265   %i = load i8, ptr %gep.fixed, align 4
266   ret i8 %i
269 define i8 @select_gep_simplifiable_1(i1 %cnd1, i1 %cnd2) {
270 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
271 ; CHECK-LABEL: define {{[^@]+}}@select_gep_simplifiable_1
272 ; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
273 ; CHECK-NEXT:  entry:
274 ; CHECK-NEXT:    [[BYTES:%.*]] = alloca [1024 x i8], align 16
275 ; CHECK-NEXT:    [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 7
276 ; CHECK-NEXT:    [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
277 ; CHECK-NEXT:    [[SEL_PTR:%.*]] = select i1 [[CND1]], ptr [[GEP7]], ptr [[GEP23]]
278 ; CHECK-NEXT:    ret i8 21
280 entry:
281   %Bytes = alloca [1024 x i8], align 16
282   %gep3 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 3
283   store i8 21, ptr %gep3, align 4
284   %gep7 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 7
285   %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23
286   %sel.ptr = select i1 %cnd1, ptr %gep7, ptr %gep23
287   store i8 42, ptr %sel.ptr, align 4
288   %i = load i8, ptr %gep3, align 4
289   ret i8 %i
292 define i8 @select_gep_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {
293 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
294 ; CHECK-LABEL: define {{[^@]+}}@select_gep_not_simplifiable_1
295 ; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
296 ; CHECK-NEXT:  entry:
297 ; CHECK-NEXT:    [[BYTES:%.*]] = alloca [1024 x i8], align 16
298 ; CHECK-NEXT:    [[GEP7:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 7
299 ; CHECK-NEXT:    store i8 1, ptr [[GEP7]], align 4
300 ; CHECK-NEXT:    [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
301 ; CHECK-NEXT:    [[SEL_PTR:%.*]] = select i1 [[CND1]], ptr [[GEP7]], ptr [[GEP23]]
302 ; CHECK-NEXT:    store i8 42, ptr [[SEL_PTR]], align 4
303 ; CHECK-NEXT:    [[I:%.*]] = load i8, ptr [[GEP7]], align 4
304 ; CHECK-NEXT:    ret i8 [[I]]
306 entry:
307   %Bytes = alloca [1024 x i8], align 16
308   %gep7 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 7
309   store i8 1, ptr %gep7, align 4
310   %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23
311   %sel.ptr = select i1 %cnd1, ptr %gep7, ptr %gep23
312   store i8 42, ptr %sel.ptr, align 4
313   %i = load i8, ptr %gep7, align 4
314   ret i8 %i
317 ; FIXME: The whole function is just "ret i8 21".
319 define i8 @phi_gep_simplifiable_1(i1 %cnd1, i1 %cnd2) {
320 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
321 ; CHECK-LABEL: define {{[^@]+}}@phi_gep_simplifiable_1
322 ; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
323 ; CHECK-NEXT:  entry:
324 ; CHECK-NEXT:    [[BYTES:%.*]] = alloca [1024 x i8], align 16
325 ; CHECK-NEXT:    br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
326 ; CHECK:       then:
327 ; CHECK-NEXT:    [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
328 ; CHECK-NEXT:    store i8 21, ptr [[GEP23]], align 4
329 ; CHECK-NEXT:    br label [[JOIN:%.*]]
330 ; CHECK:       else:
331 ; CHECK-NEXT:    [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 31
332 ; CHECK-NEXT:    store i8 21, ptr [[GEP31]], align 4
333 ; CHECK-NEXT:    br label [[JOIN]]
334 ; CHECK:       join:
335 ; CHECK-NEXT:    [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
336 ; CHECK-NEXT:    [[GEP29:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 29
337 ; CHECK-NEXT:    [[I:%.*]] = load i8, ptr [[PHI_PTR]], align 4
338 ; CHECK-NEXT:    ret i8 [[I]]
340 entry:
341   %Bytes = alloca [1024 x i8], align 16
342   br i1 %cnd1, label %then, label %else
344 then:
345   %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23
346   store i8 21, ptr %gep23, align 4
347   br label %join
349 else:
350   %gep31 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 31
351   store i8 21, ptr %gep31, align 4
352   br label %join
354 join:
355   %phi.ptr = phi ptr [%gep23, %then], [%gep31, %else]
356   ;; This store is eliminated
357   %gep29 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 29
358   store i8 42, ptr %gep29, align 4
359   %i = load i8, ptr %phi.ptr, align 4
360   ret i8 %i
363 ; FIXME: The whole function is just "ret i8 42".
365 define i8 @phi_gep_simplifiable_2(i1 %cnd1, i1 %cnd2) {
366 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
367 ; CHECK-LABEL: define {{[^@]+}}@phi_gep_simplifiable_2
368 ; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
369 ; CHECK-NEXT:  entry:
370 ; CHECK-NEXT:    [[BYTES:%.*]] = alloca [1024 x i8], align 16
371 ; CHECK-NEXT:    br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
372 ; CHECK:       then:
373 ; CHECK-NEXT:    [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
374 ; CHECK-NEXT:    br label [[JOIN:%.*]]
375 ; CHECK:       else:
376 ; CHECK-NEXT:    [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 31
377 ; CHECK-NEXT:    br label [[JOIN]]
378 ; CHECK:       join:
379 ; CHECK-NEXT:    [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
380 ; CHECK-NEXT:    ret i8 42
382 entry:
383   %Bytes = alloca [1024 x i8], align 16
384   %gep29 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 29
385   ;; This store is propagated to the load.
386   store i8 42, ptr %gep29, align 4
387   br i1 %cnd1, label %then, label %else
389 then:
390   %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23
391   br label %join
393 else:
394   %gep31 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 31
395   br label %join
397 join:
398   %phi.ptr = phi ptr [%gep23, %then], [%gep31, %else]
399   store i8 21, ptr %phi.ptr, align 4
400   ;; Replaced with the constant, and both store/load are eliminated.
401   %i = load i8, ptr %gep29, align 4
402   ret i8 %i
405 define i8 @phi_gep_not_simplifiable_1(i1 %cnd1, i1 %cnd2) {
406 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
407 ; CHECK-LABEL: define {{[^@]+}}@phi_gep_not_simplifiable_1
408 ; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
409 ; CHECK-NEXT:  entry:
410 ; CHECK-NEXT:    [[BYTES:%.*]] = alloca [1024 x i8], align 16
411 ; CHECK-NEXT:    [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
412 ; CHECK-NEXT:    br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
413 ; CHECK:       then:
414 ; CHECK-NEXT:    br label [[JOIN:%.*]]
415 ; CHECK:       else:
416 ; CHECK-NEXT:    [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 31
417 ; CHECK-NEXT:    br label [[JOIN]]
418 ; CHECK:       join:
419 ; CHECK-NEXT:    [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
420 ; CHECK-NEXT:    store i8 42, ptr [[GEP23]], align 4
421 ; CHECK-NEXT:    [[I:%.*]] = load i8, ptr [[PHI_PTR]], align 4
422 ; CHECK-NEXT:    ret i8 [[I]]
424 entry:
425   %Bytes = alloca [1024 x i8], align 16
426   %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23
427   br i1 %cnd1, label %then, label %else
429 then:
430   br label %join
432 else:
433   %gep31 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 31
434   br label %join
436 join:
437   %phi.ptr = phi ptr [%gep23, %then], [%gep31, %else]
438   ;; This store cannot be eliminated
439   store i8 42, ptr %gep23, align 4
440   %i = load i8, ptr %phi.ptr, align 4
441   ret i8 %i
444 define i8 @phi_gep_not_simplifiable_2(i1 %cnd1, i1 %cnd2) {
445 ; CHECK-LABEL: define {{[^@]+}}@phi_gep_not_simplifiable_2
446 ; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) {
447 ; CHECK-NEXT:  entry:
448 ; CHECK-NEXT:    [[BYTES:%.*]] = call ptr @calloc(i64 noundef 1024, i64 noundef 1)
449 ; CHECK-NEXT:    [[GEP23:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 23
450 ; CHECK-NEXT:    br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
451 ; CHECK:       then:
452 ; CHECK-NEXT:    br label [[JOIN:%.*]]
453 ; CHECK:       else:
454 ; CHECK-NEXT:    [[GEP31:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 31
455 ; CHECK-NEXT:    br label [[JOIN]]
456 ; CHECK:       join:
457 ; CHECK-NEXT:    [[PHI_PTR:%.*]] = phi ptr [ [[GEP23]], [[THEN]] ], [ [[GEP31]], [[ELSE]] ]
458 ; CHECK-NEXT:    store i8 21, ptr [[PHI_PTR]], align 4
459 ; CHECK-NEXT:    [[I:%.*]] = load i8, ptr [[GEP23]], align 4
460 ; CHECK-NEXT:    ret i8 [[I]]
462 entry:
463   %Bytes = call ptr @calloc(i64 1024, i64 1)
464   %gep23 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 23
465   br i1 %cnd1, label %then, label %else
467 then:
468   br label %join
470 else:
471   %gep31 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 31
472   br label %join
474 join:
475   %phi.ptr = phi ptr [%gep23, %then], [%gep31, %else]
476   store i8 21, ptr %phi.ptr, align 4
477   %i = load i8, ptr %gep23, align 4
478   ret i8 %i
481 define i8 @phi_offsets(i1 %cnd1, i1 %cnd2) {
482 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
483 ; CHECK-LABEL: define {{[^@]+}}@phi_offsets
484 ; CHECK-SAME: (i1 noundef [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR1]] {
485 ; CHECK-NEXT:  entry:
486 ; CHECK-NEXT:    [[BYTES:%.*]] = alloca [1024 x i8], align 16
487 ; CHECK-NEXT:    br i1 [[CND1]], label [[THEN:%.*]], label [[ELSE:%.*]]
488 ; CHECK:       then:
489 ; CHECK-NEXT:    br label [[JOIN:%.*]]
490 ; CHECK:       else:
491 ; CHECK-NEXT:    br label [[JOIN]]
492 ; CHECK:       join:
493 ; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ 3, [[THEN]] ], [ 11, [[ELSE]] ]
494 ; CHECK-NEXT:    [[GEP_PHI:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[PHI]]
495 ; CHECK-NEXT:    ret i8 100
497 entry:
498   %Bytes = alloca [1024 x i8], align 16
499   store i8 100, ptr %Bytes, align 4
500   br i1 %cnd1, label %then, label %else
502 then:
503   br label %join
505 else:
506   br label %join
508 join:
509   %phi = phi i64 [ 3, %then ], [ 11, %else ]
510   %gep.phi = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %phi
511   store i8 42, ptr %gep.phi, align 4
512   %i = load i8, ptr %Bytes, align 4
513   ret i8 %i
517 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" }
518 ; CHECK: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
520 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
521 ; CGSCC: {{.*}}
522 ; TUNIT: {{.*}}