xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/geps-pointers-to-structs.ll (revision fbcf8a8cbb2461730bfd0603b396842925a88ef2)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4%struct.1 = type { i32, i64, i8 }
5%struct.2 = type { i32, [20 x i64], i8 }
6
7define i1 @test.ult.true.due.to.first.dimension(ptr %start, ptr %high) {
8; CHECK-LABEL: @test.ult.true.due.to.first.dimension(
9; CHECK-NEXT:  entry:
10; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 6, i32 0
11; CHECK-NEXT:    [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
12; CHECK-NEXT:    [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
13; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
14; CHECK:       if.then:
15; CHECK-NEXT:    [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 5, i32 0
16; CHECK-NEXT:    [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
17; CHECK-NEXT:    ret i1 true
18; CHECK:       if.end:
19; CHECK-NEXT:    ret i1 true
20;
21entry:
22  %add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 6, i32 0
23  %add.ptr.cast = bitcast ptr %add.ptr to ptr
24  %c.1 = icmp ule ptr %add.ptr.cast, %high
25  br i1 %c.1, label %if.then, label %if.end
26
27if.then:
28  %start.0 = getelementptr inbounds %struct.1, ptr %start, i64 5, i32 0
29  %start.0.cast = bitcast ptr %start.0 to ptr
30  %c.0 = icmp ult ptr %start.0.cast, %high
31  ret i1 %c.0
32
33if.end:
34  ret i1 true
35}
36
37define i1 @test.ult.true.due.to.first.dimension.var.index.0(ptr %start, ptr %high, i32 %idx) {
38; CHECK-LABEL: @test.ult.true.due.to.first.dimension.var.index.0(
39; CHECK-NEXT:  entry:
40; CHECK-NEXT:    [[IDX_EXT_PLUS_1:%.*]] = add nuw nsw i32 [[IDX:%.*]], 1
41; CHECK-NEXT:    [[IDX_EXT_PLUS_1_EXT:%.*]] = zext i32 [[IDX_EXT_PLUS_1]] to i64
42; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 [[IDX_EXT_PLUS_1_EXT]], i32 0
43; CHECK-NEXT:    [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
44; CHECK-NEXT:    [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
45; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
46; CHECK:       if.then:
47; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
48; CHECK-NEXT:    [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 [[IDX_EXT]], i32 0
49; CHECK-NEXT:    [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
50; CHECK-NEXT:    ret i1 true
51; CHECK:       if.end:
52; CHECK-NEXT:    ret i1 true
53;
54entry:
55  %idx.ext.plus.1 = add nuw nsw i32 %idx, 1
56  %idx.ext.plus.1.ext = zext i32 %idx.ext.plus.1 to i64
57  %add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext.plus.1.ext, i32 0
58  %add.ptr.cast = bitcast ptr %add.ptr to ptr
59  %c.1 = icmp ule ptr %add.ptr.cast, %high
60  br i1 %c.1, label %if.then, label %if.end
61
62if.then:
63  %idx.ext = zext i32 %idx to i64
64  %start.0 = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext, i32 0
65  %start.0.cast = bitcast ptr %start.0 to ptr
66  %c.0 = icmp ult ptr %start.0.cast, %high
67  ret i1 %c.0
68
69if.end:
70  ret i1 true
71}
72
73define i1 @test.ult.true.due.to.first.dimension.var.index.1(ptr %start, ptr %high, i32 %idx) {
74; CHECK-LABEL: @test.ult.true.due.to.first.dimension.var.index.1(
75; CHECK-NEXT:  entry:
76; CHECK-NEXT:    [[IDX_EXT_PLUS_1:%.*]] = add nuw nsw i32 [[IDX:%.*]], 1
77; CHECK-NEXT:    [[IDX_EXT_PLUS_1_EXT:%.*]] = zext i32 [[IDX_EXT_PLUS_1]] to i64
78; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 [[IDX_EXT_PLUS_1_EXT]], i32 0
79; CHECK-NEXT:    [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
80; CHECK-NEXT:    [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
81; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
82; CHECK:       if.then:
83; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
84; CHECK-NEXT:    [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 [[IDX_EXT]], i32 1
85; CHECK-NEXT:    [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
86; CHECK-NEXT:    ret i1 true
87; CHECK:       if.end:
88; CHECK-NEXT:    ret i1 true
89;
90entry:
91  %idx.ext.plus.1 = add nuw nsw i32 %idx, 1
92  %idx.ext.plus.1.ext = zext i32 %idx.ext.plus.1 to i64
93  %add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext.plus.1.ext, i32 0
94  %add.ptr.cast = bitcast ptr %add.ptr to ptr
95  %c.1 = icmp ule ptr %add.ptr.cast, %high
96  br i1 %c.1, label %if.then, label %if.end
97
98if.then:
99  %idx.ext = zext i32 %idx to i64
100  %start.0 = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext, i32 1
101  %start.0.cast = bitcast ptr %start.0 to ptr
102  %c.0 = icmp ult ptr %start.0.cast, %high
103  ret i1 %c.0
104
105if.end:
106  ret i1 true
107}
108
109define i1 @test.ult.true.due.to.first.dimension.var.index.2(ptr %start, ptr %high, i32 %idx) {
110; CHECK-LABEL: @test.ult.true.due.to.first.dimension.var.index.2(
111; CHECK-NEXT:  entry:
112; CHECK-NEXT:    [[IDX_EXT_PLUS_1:%.*]] = add nuw nsw i32 [[IDX:%.*]], 1
113; CHECK-NEXT:    [[IDX_EXT_PLUS_1_EXT:%.*]] = zext i32 [[IDX_EXT_PLUS_1]] to i64
114; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 [[IDX_EXT_PLUS_1_EXT]], i32 0
115; CHECK-NEXT:    [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
116; CHECK-NEXT:    [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
117; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
118; CHECK:       if.then:
119; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
120; CHECK-NEXT:    [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 [[IDX_EXT]], i32 2
121; CHECK-NEXT:    ret i1 true
122; CHECK:       if.end:
123; CHECK-NEXT:    ret i1 true
124;
125entry:
126  %idx.ext.plus.1 = add nuw nsw i32 %idx, 1
127  %idx.ext.plus.1.ext = zext i32 %idx.ext.plus.1 to i64
128  %add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext.plus.1.ext, i32 0
129  %add.ptr.cast = bitcast ptr %add.ptr to ptr
130  %c.1 = icmp ule ptr %add.ptr.cast, %high
131  br i1 %c.1, label %if.then, label %if.end
132
133if.then:
134  %idx.ext = zext i32 %idx to i64
135  %start.0 = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext, i32 2
136  %c.0 = icmp ult ptr %start.0, %high
137  ret i1 %c.0
138
139if.end:
140  ret i1 true
141}
142
143define i1 @test.ult.unknown.due.to.first.dimension(ptr %start, ptr %high) {
144; CHECK-LABEL: @test.ult.unknown.due.to.first.dimension(
145; CHECK-NEXT:  entry:
146; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 5, i32 0
147; CHECK-NEXT:    [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
148; CHECK-NEXT:    [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
149; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
150; CHECK:       if.then:
151; CHECK-NEXT:    [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 6, i32 0
152; CHECK-NEXT:    [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
153; CHECK-NEXT:    [[C_0:%.*]] = icmp ult ptr [[START_0_CAST]], [[HIGH]]
154; CHECK-NEXT:    ret i1 [[C_0]]
155; CHECK:       if.end:
156; CHECK-NEXT:    ret i1 true
157;
158entry:
159  %add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 5, i32 0
160  %add.ptr.cast = bitcast ptr %add.ptr to ptr
161  %c.1 = icmp ule ptr %add.ptr.cast, %high
162  br i1 %c.1, label %if.then, label %if.end
163
164if.then:
165  %start.0 = getelementptr inbounds %struct.1, ptr %start, i64 6, i32 0
166  %start.0.cast = bitcast ptr %start.0 to ptr
167  %c.0 = icmp ult ptr %start.0.cast, %high
168  ret i1 %c.0
169
170if.end:
171  ret i1 true
172}
173
174define i1 @test.ult.true.due.to.second.dimension(ptr %start, ptr %high) {
175; CHECK-LABEL: @test.ult.true.due.to.second.dimension(
176; CHECK-NEXT:  entry:
177; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 5, i32 2
178; CHECK-NEXT:    [[C_1:%.*]] = icmp ule ptr [[ADD_PTR]], [[HIGH:%.*]]
179; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
180; CHECK:       if.then:
181; CHECK-NEXT:    [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 5, i32 1
182; CHECK-NEXT:    [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
183; CHECK-NEXT:    ret i1 true
184; CHECK:       if.end:
185; CHECK-NEXT:    ret i1 true
186;
187entry:
188  %add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 5, i32 2
189  %c.1 = icmp ule ptr %add.ptr, %high
190  br i1 %c.1, label %if.then, label %if.end
191
192if.then:
193  %start.0 = getelementptr inbounds %struct.1, ptr %start, i64 5, i32 1
194  %start.0.cast = bitcast ptr %start.0 to ptr
195  %c.0 = icmp ult ptr %start.0.cast, %high
196  ret i1 %c.0
197
198if.end:
199  ret i1 true
200}
201
202define i1 @test.ult.unknown.due.to.second.dimension(ptr %start, ptr %high) {
203; CHECK-LABEL: @test.ult.unknown.due.to.second.dimension(
204; CHECK-NEXT:  entry:
205; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 5, i32 2
206; CHECK-NEXT:    [[C_1:%.*]] = icmp ule ptr [[ADD_PTR]], [[HIGH:%.*]]
207; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
208; CHECK:       if.then:
209; CHECK-NEXT:    [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 5, i32 2
210; CHECK-NEXT:    [[C_0:%.*]] = icmp ult ptr [[START_0]], [[HIGH]]
211; CHECK-NEXT:    ret i1 [[C_0]]
212; CHECK:       if.end:
213; CHECK-NEXT:    ret i1 true
214;
215entry:
216  %add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 5, i32 2
217  %c.1 = icmp ule ptr %add.ptr, %high
218  br i1 %c.1, label %if.then, label %if.end
219
220if.then:
221  %start.0 = getelementptr inbounds %struct.1, ptr %start, i64 5, i32 2
222  %c.0 = icmp ult ptr %start.0, %high
223  ret i1 %c.0
224
225if.end:
226  ret i1 true
227}
228
229define i1 @test.ult.unknown.due.to.second.dimension.var.index.0(ptr %start, ptr %high, i32 %idx) {
230; CHECK-LABEL: @test.ult.unknown.due.to.second.dimension.var.index.0(
231; CHECK-NEXT:  entry:
232; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX:%.*]] to i64
233; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 [[IDX_EXT]], i32 0
234; CHECK-NEXT:    [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
235; CHECK-NEXT:    [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
236; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
237; CHECK:       if.then:
238; CHECK-NEXT:    [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 [[IDX_EXT]], i32 1
239; CHECK-NEXT:    [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
240; CHECK-NEXT:    [[C_0:%.*]] = icmp ult ptr [[START_0_CAST]], [[HIGH]]
241; CHECK-NEXT:    ret i1 [[C_0]]
242; CHECK:       if.end:
243; CHECK-NEXT:    ret i1 true
244;
245entry:
246  %idx.ext = zext i32 %idx to i64
247  %add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext, i32 0
248  %add.ptr.cast = bitcast ptr %add.ptr to ptr
249  %c.1 = icmp ule ptr %add.ptr.cast, %high
250  br i1 %c.1, label %if.then, label %if.end
251
252if.then:
253  %start.0 = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext, i32 1
254  %start.0.cast = bitcast ptr %start.0 to ptr
255  %c.0 = icmp ult ptr %start.0.cast, %high
256  ret i1 %c.0
257
258if.end:
259  ret i1 true
260}
261
262define i1 @test.ult.unknown.due.to.second.dimension.var.index.1(ptr %start, ptr %high, i32 %idx) {
263; CHECK-LABEL: @test.ult.unknown.due.to.second.dimension.var.index.1(
264; CHECK-NEXT:  entry:
265; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX:%.*]] to i64
266; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_1:%.*]], ptr [[START:%.*]], i64 [[IDX_EXT]], i32 1
267; CHECK-NEXT:    [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
268; CHECK-NEXT:    [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
269; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
270; CHECK:       if.then:
271; CHECK-NEXT:    [[START_0:%.*]] = getelementptr inbounds [[STRUCT_1]], ptr [[START]], i64 [[IDX_EXT]], i32 2
272; CHECK-NEXT:    [[C_0:%.*]] = icmp ult ptr [[START_0]], [[HIGH]]
273; CHECK-NEXT:    ret i1 [[C_0]]
274; CHECK:       if.end:
275; CHECK-NEXT:    ret i1 true
276;
277entry:
278  %idx.ext = zext i32 %idx to i64
279  %add.ptr = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext, i32 1
280  %add.ptr.cast = bitcast ptr %add.ptr to ptr
281  %c.1 = icmp ule ptr %add.ptr.cast, %high
282  br i1 %c.1, label %if.then, label %if.end
283
284if.then:
285  %start.0 = getelementptr inbounds %struct.1, ptr %start, i64 %idx.ext, i32 2
286  %c.0 = icmp ult ptr %start.0, %high
287  ret i1 %c.0
288
289if.end:
290  ret i1 true
291}
292
293define i1 @ptr.int.struct.test.ult.true.due.to.first.dimension(ptr %start, ptr %high) {
294; CHECK-LABEL: @ptr.int.struct.test.ult.true.due.to.first.dimension(
295; CHECK-NEXT:  entry:
296; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_2:%.*]], ptr [[START:%.*]], i64 6, i32 1, i32 5
297; CHECK-NEXT:    [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
298; CHECK-NEXT:    [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
299; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
300; CHECK:       if.then:
301; CHECK-NEXT:    [[START_0:%.*]] = getelementptr inbounds [[STRUCT_2]], ptr [[START]], i64 6, i32 0
302; CHECK-NEXT:    [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
303; CHECK-NEXT:    ret i1 true
304; CHECK:       if.end:
305; CHECK-NEXT:    ret i1 true
306;
307entry:
308  %add.ptr = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 1, i32 5
309  %add.ptr.cast = bitcast ptr %add.ptr to ptr
310  %c.1 = icmp ule ptr %add.ptr.cast, %high
311  br i1 %c.1, label %if.then, label %if.end
312
313if.then:
314  %start.0 = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 0
315  %start.0.cast = bitcast ptr %start.0 to ptr
316  %c.0 = icmp ult ptr %start.0.cast, %high
317  ret i1 %c.0
318
319if.end:
320  ret i1 true
321}
322
323define i1 @ptr.int.struct.test.ult.true.due.to.third.dimension.var.index(ptr %start, ptr %high, i32 %idx) {
324; CHECK-LABEL: @ptr.int.struct.test.ult.true.due.to.third.dimension.var.index(
325; CHECK-NEXT:  entry:
326; CHECK-NEXT:    [[IDX_EXT_PLUS_1:%.*]] = add nuw nsw i32 [[IDX:%.*]], 1
327; CHECK-NEXT:    [[IDX_EXT_PLUS_1_EXT:%.*]] = zext i32 [[IDX_EXT_PLUS_1]] to i64
328; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_2:%.*]], ptr [[START:%.*]], i64 6, i32 1, i64 [[IDX_EXT_PLUS_1_EXT]]
329; CHECK-NEXT:    [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
330; CHECK-NEXT:    [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
331; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
332; CHECK:       if.then:
333; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
334; CHECK-NEXT:    [[START_0:%.*]] = getelementptr inbounds [[STRUCT_2]], ptr [[START]], i64 6, i32 1, i64 [[IDX_EXT]]
335; CHECK-NEXT:    [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
336; CHECK-NEXT:    ret i1 true
337; CHECK:       if.end:
338; CHECK-NEXT:    ret i1 true
339;
340entry:
341  %idx.ext.plus.1 = add nuw nsw i32 %idx, 1
342  %idx.ext.plus.1.ext = zext i32 %idx.ext.plus.1 to i64
343  %add.ptr = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 1, i64 %idx.ext.plus.1.ext
344  %add.ptr.cast = bitcast ptr %add.ptr to ptr
345  %c.1 = icmp ule ptr %add.ptr.cast, %high
346  br i1 %c.1, label %if.then, label %if.end
347
348if.then:
349  %idx.ext = zext i32 %idx to i64
350  %start.0 = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 1, i64 %idx.ext
351  %start.0.cast = bitcast ptr %start.0 to ptr
352  %c.0 = icmp ult ptr %start.0.cast, %high
353  ret i1 %c.0
354
355if.end:
356  ret i1 true
357}
358
359define i1 @ptr.int.struct.test.ult.due.to.second.dimension.var.index(ptr %start, ptr %high, i32 %idx) {
360; CHECK-LABEL: @ptr.int.struct.test.ult.due.to.second.dimension.var.index(
361; CHECK-NEXT:  entry:
362; CHECK-NEXT:    [[IDX_EXT_PLUS_1:%.*]] = add nuw nsw i32 [[IDX:%.*]], 1
363; CHECK-NEXT:    [[IDX_EXT_PLUS_1_EXT:%.*]] = zext i32 [[IDX_EXT_PLUS_1]] to i64
364; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_2:%.*]], ptr [[START:%.*]], i64 6, i32 1, i64 [[IDX_EXT_PLUS_1_EXT]]
365; CHECK-NEXT:    [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
366; CHECK-NEXT:    [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
367; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
368; CHECK:       if.then:
369; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
370; CHECK-NEXT:    [[START_0:%.*]] = getelementptr inbounds [[STRUCT_2]], ptr [[START]], i64 6, i32 0
371; CHECK-NEXT:    [[START_0_CAST:%.*]] = bitcast ptr [[START_0]] to ptr
372; CHECK-NEXT:    ret i1 true
373; CHECK:       if.end:
374; CHECK-NEXT:    ret i1 true
375;
376entry:
377  %idx.ext.plus.1 = add nuw nsw i32 %idx, 1
378  %idx.ext.plus.1.ext = zext i32 %idx.ext.plus.1 to i64
379  %add.ptr = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 1, i64 %idx.ext.plus.1.ext
380  %add.ptr.cast = bitcast ptr %add.ptr to ptr
381  %c.1 = icmp ule ptr %add.ptr.cast, %high
382  br i1 %c.1, label %if.then, label %if.end
383
384if.then:
385  %idx.ext = zext i32 %idx to i64
386  %start.0 = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 0
387  %start.0.cast = bitcast ptr %start.0 to ptr
388  %c.0 = icmp ult ptr %start.0.cast, %high
389  ret i1 %c.0
390
391if.end:
392  ret i1 true
393}
394
395define i1 @ptr.int.struct.test.ult.unknown.due.to.second.dimension.var.index(ptr %start, ptr %high, i32 %idx) {
396; CHECK-LABEL: @ptr.int.struct.test.ult.unknown.due.to.second.dimension.var.index(
397; CHECK-NEXT:  entry:
398; CHECK-NEXT:    [[IDX_EXT_PLUS_1:%.*]] = add nuw nsw i32 [[IDX:%.*]], 1
399; CHECK-NEXT:    [[IDX_EXT_PLUS_1_EXT:%.*]] = zext i32 [[IDX_EXT_PLUS_1]] to i64
400; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds [[STRUCT_2:%.*]], ptr [[START:%.*]], i64 6, i32 1, i64 [[IDX_EXT_PLUS_1_EXT]]
401; CHECK-NEXT:    [[ADD_PTR_CAST:%.*]] = bitcast ptr [[ADD_PTR]] to ptr
402; CHECK-NEXT:    [[C_1:%.*]] = icmp ule ptr [[ADD_PTR_CAST]], [[HIGH:%.*]]
403; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
404; CHECK:       if.then:
405; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
406; CHECK-NEXT:    [[START_0:%.*]] = getelementptr inbounds [[STRUCT_2]], ptr [[START]], i64 6, i32 2
407; CHECK-NEXT:    [[C_0:%.*]] = icmp ult ptr [[START_0]], [[HIGH]]
408; CHECK-NEXT:    ret i1 [[C_0]]
409; CHECK:       if.end:
410; CHECK-NEXT:    ret i1 true
411;
412entry:
413  %idx.ext.plus.1 = add nuw nsw i32 %idx, 1
414  %idx.ext.plus.1.ext = zext i32 %idx.ext.plus.1 to i64
415  %add.ptr = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 1, i64 %idx.ext.plus.1.ext
416  %add.ptr.cast = bitcast ptr %add.ptr to ptr
417  %c.1 = icmp ule ptr %add.ptr.cast, %high
418  br i1 %c.1, label %if.then, label %if.end
419
420if.then:
421  %idx.ext = zext i32 %idx to i64
422  %start.0 = getelementptr inbounds %struct.2, ptr %start, i64 6, i32 2
423  %c.0 = icmp ult ptr %start.0, %high
424  ret i1 %c.0
425
426if.end:
427  ret i1 true
428}
429