xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/gep-add-multiple-indices.ll (revision d045e23c2d00a445e40a8c97471df023d8364f59)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
5
6define i1 @test_outer_gep_last_index_no_overflow_all_inbounds_1(ptr %dst) {
7; CHECK-LABEL: @test_outer_gep_last_index_no_overflow_all_inbounds_1(
8; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 0
9; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2
10; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1
11; CHECK-NEXT:    ret i1 true
12;
13  %dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0
14  %upper = getelementptr inbounds ptr, ptr %dst, i64 2
15  %gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 1
16  %c.1 = icmp ult ptr %gep.1, %upper
17  ret i1 %c.1
18}
19
20define i1 @test_outer_gep_last_index_no_overflow_all_inbounds_2(ptr %dst) {
21; CHECK-LABEL: @test_outer_gep_last_index_no_overflow_all_inbounds_2(
22; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 0
23; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 3
24; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1
25; CHECK-NEXT:    ret i1 true
26;
27  %dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0
28  %upper = getelementptr inbounds ptr, ptr %dst, i64 3
29  %gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 1
30  %c.1 = icmp ult ptr %gep.1, %upper
31  ret i1 %c.1
32}
33
34define i1 @test_outer_gep_last_index_overflow_all_inbounds(ptr %dst) {
35; CHECK-LABEL: @test_outer_gep_last_index_overflow_all_inbounds(
36; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 0
37; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2
38; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 2
39; CHECK-NEXT:    ret i1 false
40;
41  %dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0
42  %upper = getelementptr inbounds ptr, ptr %dst, i64 2
43  %gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 2
44  %c = icmp ult ptr %gep.1, %upper
45  ret i1 %c
46}
47
48define i1 @test_inner_gep_multiple_indices_ult_true_all_inbounds(ptr %dst) {
49; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_true_all_inbounds(
50; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
51; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
52; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
53; CHECK-NEXT:    ret i1 true
54;
55  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
56  %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
57  %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
58  %c = icmp ult ptr %gep.1, %upper
59  ret i1 %c
60}
61
62define i1 @test_inner_gep_multiple_indices_uge_true_all_inbounds(ptr %dst) {
63; CHECK-LABEL: @test_inner_gep_multiple_indices_uge_true_all_inbounds(
64; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
65; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
66; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
67; CHECK-NEXT:    ret i1 true
68;
69  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
70  %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
71  %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
72  %c = icmp uge ptr %gep.1, %dst.0
73  ret i1 %c
74}
75
76define i1 @test_inner_gep_multiple_indices_ult_false_all_inbounds(ptr %dst) {
77; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_false_all_inbounds(
78; CHECK-NEXT:  entry:
79; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
80; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
81; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 2
82; CHECK-NEXT:    ret i1 false
83;
84entry:
85  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
86  %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
87  %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 2
88  %c = icmp ult ptr %gep.1, %upper
89  ret i1 %c
90}
91
92define i1 @test_inner_gep_multiple_indices_uge_true_all_inbounds_2(ptr %dst) {
93; CHECK-LABEL: @test_inner_gep_multiple_indices_uge_true_all_inbounds_2(
94; CHECK-NEXT:  entry:
95; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
96; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
97; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 2
98; CHECK-NEXT:    ret i1 true
99;
100entry:
101  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
102  %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
103  %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 2
104  %c = icmp uge ptr %gep.1, %dst.0
105  ret i1 %c
106}
107
108define i1 @test_inner_gep_multiple_indices_ult_true_inc_gep_all_inbounds_overflow(ptr %dst) {
109; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_true_inc_gep_all_inbounds_overflow(
110; CHECK-NEXT:  entry:
111; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
112; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 6
113; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 2
114; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
115; CHECK-NEXT:    ret i1 [[C]]
116;
117entry:
118  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
119  %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 6
120  %gep.1 = getelementptr i32, ptr %dst.0, i64 2
121  %c = icmp ult ptr %gep.1, %upper
122  ret i1 %c
123}
124
125define i1 @test_inner_gep_multiple_indices_ult_true_inc_gep_not_inbounds(ptr %dst) {
126; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_true_inc_gep_not_inbounds(
127; CHECK-NEXT:  entry:
128; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
129; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
130; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 1
131; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
132; CHECK-NEXT:    ret i1 [[C]]
133;
134entry:
135  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
136  %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
137  %gep.1 = getelementptr i32, ptr %dst.0, i64 1
138  %c = icmp ult ptr %gep.1, %upper
139  ret i1 %c
140}
141
142define i1 @test_inner_gep_multiple_indices_uge_true_inc_gep_not_inbounds(ptr %dst) {
143; CHECK-LABEL: @test_inner_gep_multiple_indices_uge_true_inc_gep_not_inbounds(
144; CHECK-NEXT:  entry:
145; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
146; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
147; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 1
148; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
149; CHECK-NEXT:    ret i1 [[C]]
150;
151entry:
152  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
153  %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
154  %gep.1 = getelementptr i32, ptr %dst.0, i64 1
155  %c = icmp ult ptr %gep.1, %upper
156  ret i1 %c
157}
158
159define i1 @test_inner_gep_multiple_indices_ult_false_inc_gep_not_inbounds(ptr %dst) {
160; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_false_inc_gep_not_inbounds(
161; CHECK-NEXT:  entry:
162; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
163; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
164; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 2
165; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
166; CHECK-NEXT:    ret i1 [[C]]
167;
168entry:
169  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
170  %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
171  %gep.1 = getelementptr i32, ptr %dst.0, i64 2
172  %c = icmp ult ptr %gep.1, %upper
173  ret i1 %c
174}
175
176define i1 @test_inner_gep_multiple_indices_ult_true_inc_gep_not_inbounds_overflow(ptr %dst) {
177; CHECK-LABEL: @test_inner_gep_multiple_indices_ult_true_inc_gep_not_inbounds_overflow(
178; CHECK-NEXT:  entry:
179; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
180; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 5
181; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr i32, ptr [[DST_0]], i64 2
182; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
183; CHECK-NEXT:    ret i1 [[C]]
184;
185entry:
186  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
187  %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 5
188  %gep.1 = getelementptr i32, ptr %dst.0, i64 2
189  %c = icmp ult ptr %gep.1, %upper
190  ret i1 %c
191}
192
193define i1 @test_inner_gep_multi_index(ptr %dst) {
194; CHECK-LABEL: @test_inner_gep_multi_index(
195; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds ptr, ptr [[DST:%.*]], i64 0
196; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2
197; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1
198; CHECK-NEXT:    ret i1 true
199;
200  %dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0
201  %upper = getelementptr inbounds ptr, ptr %dst, i64 2
202  %gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 1
203  %c.1 = icmp ult ptr %gep.1, %upper
204  ret i1 %c.1
205}
206
207define i1 @test_inner_gep_multi_index_outer_gep_last_index_no_overflow_all_inbounds(ptr %dst) {
208; CHECK-LABEL: @test_inner_gep_multi_index_outer_gep_last_index_no_overflow_all_inbounds(
209; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 0
210; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2
211; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1
212; CHECK-NEXT:    ret i1 true
213;
214  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
215  %upper = getelementptr inbounds ptr, ptr %dst, i64 2
216  %gep.1 = getelementptr inbounds [2 x i32] , ptr %dst.0, i64 1, i64 1
217  %c.1 = icmp ult ptr %gep.1, %upper
218  ret i1 %c.1
219}
220
221define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_1(ptr %dst) {
222; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_1(
223; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 0, i64 1
224; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 2
225; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
226; CHECK-NEXT:    ret i1 false
227;
228  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 1
229  %upper = getelementptr inbounds i32, ptr %dst, i64 2
230  %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
231  %c.1 = icmp ult ptr %gep.1, %upper
232  ret i1 %c.1
233}
234
235define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_2(ptr %dst) {
236; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_2(
237; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 1, i64 0
238; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 2
239; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
240; CHECK-NEXT:    ret i1 false
241;
242  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 1, i64 0
243  %upper = getelementptr inbounds i32, ptr %dst, i64 2
244  %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
245  %c.1 = icmp ult ptr %gep.1, %upper
246  ret i1 %c.1
247}
248
249define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_3(ptr %dst) {
250; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_3(
251; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 1, i64 0
252; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 3
253; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
254; CHECK-NEXT:    ret i1 false
255;
256  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 1, i64 0
257  %upper = getelementptr inbounds i32, ptr %dst, i64 3
258  %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
259  %c.1 = icmp ult ptr %gep.1, %upper
260  ret i1 %c.1
261}
262
263define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_4(ptr %dst) {
264; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_4(
265; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 1, i64 0
266; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 4
267; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
268; CHECK-NEXT:    ret i1 true
269;
270  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 1, i64 0
271  %upper = getelementptr inbounds i32, ptr %dst, i64 4
272  %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
273  %c.1 = icmp ult ptr %gep.1, %upper
274  ret i1 %c.1
275}
276
277define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_5(i64 %off, ptr %dst) {
278; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_5(
279; CHECK-NEXT:    [[OFF_ULT:%.*]] = icmp ule i64 [[OFF:%.*]], 2
280; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 2, i64 0
281; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 5
282; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
283; CHECK-NEXT:    ret i1 true
284;
285  %off.ult = icmp ule i64 %off, 2
286  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 2, i64 0
287  %upper = getelementptr inbounds i32, ptr %dst, i64 5
288  %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
289  %c.1 = icmp ule ptr %gep.1, %upper
290  ret i1 %c.1
291}
292
293define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_6(i64 %off, ptr %dst) {
294; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_6(
295; CHECK-NEXT:    [[OFF_ULT:%.*]] = icmp ule i64 [[OFF:%.*]], 2
296; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 2, i64 0
297; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 5
298; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
299; CHECK-NEXT:    ret i1 false
300;
301  %off.ult = icmp ule i64 %off, 2
302  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 2, i64 0
303  %upper = getelementptr inbounds i32, ptr %dst, i64 5
304  %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
305  %c.1 = icmp ult ptr %gep.1, %upper
306  ret i1 %c.1
307}
308
309define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_7(i64 %off, ptr %dst) {
310; CHECK-LABEL: @test_inner_gep_multi_index_no_overflow_all_inbounds_7(
311; CHECK-NEXT:    [[OFF_ULT:%.*]] = icmp ule i64 [[OFF:%.*]], 2
312; CHECK-NEXT:    [[DST_0:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST:%.*]], i64 2, i64 0
313; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[OFF]]
314; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
315; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
316; CHECK-NEXT:    ret i1 [[C_1]]
317;
318  %off.ult = icmp ule i64 %off, 2
319  %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 2, i64 0
320  %upper = getelementptr inbounds i32, ptr %dst, i64 %off
321  %gep.1 = getelementptr inbounds i32, ptr %dst.0, i64 1
322  %c.1 = icmp ult ptr %gep.1, %upper
323  ret i1 %c.1
324}
325