1175d68ddSFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
227d1d8bcSRoman Lebedev; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3175d68ddSFlorian Hahn
4175d68ddSFlorian Hahn; Tests for using inbounds information from GEPs where the GEP only causes UB in the use blocks.
5175d68ddSFlorian Hahn
6*34e477e9SFlorian Hahndeclare void @noundef(ptr noundef) willreturn nounwind
7*34e477e9SFlorian Hahndeclare void @noundef2(ptr noundef)
8175d68ddSFlorian Hahn
9175d68ddSFlorian Hahndeclare void @use(i1)
10175d68ddSFlorian Hahn
11175d68ddSFlorian Hahn; %start + %n.ext is guaranteed to not overflow (due to inbounds).
12175d68ddSFlorian Hahn; %start + %idx.ext does not overflow if %idx.ext <= %n.ext.
13*34e477e9SFlorian Hahndefine i1 @inbounds_poison_is_ub_in_use_block_1(ptr %src, i32 %n, i32 %idx) {
14175d68ddSFlorian Hahn; CHECK-LABEL: @inbounds_poison_is_ub_in_use_block_1(
15175d68ddSFlorian Hahn; CHECK-NEXT:  entry:
16175d68ddSFlorian Hahn; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64
17*34e477e9SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]]
18175d68ddSFlorian Hahn; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]]
19175d68ddSFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
20*34e477e9SFlorian Hahn; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]]
21175d68ddSFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]]
22175d68ddSFlorian Hahn; CHECK:       then:
23*34e477e9SFlorian Hahn; CHECK-NEXT:    call void @noundef(ptr [[UPPER]])
24*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]
25175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_UPPER_1]]
26175d68ddSFlorian Hahn; CHECK:       else:
27*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]
28175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_UPPER_2]]
29175d68ddSFlorian Hahn;
30175d68ddSFlorian Hahnentry:
31175d68ddSFlorian Hahn  %n.ext = zext i32 %n to i64
32*34e477e9SFlorian Hahn  %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext
33175d68ddSFlorian Hahn  %cmp.idx = icmp ult i32 %idx, %n
34175d68ddSFlorian Hahn  %idx.ext = zext i32 %idx to i64
35*34e477e9SFlorian Hahn  %src.idx = getelementptr i32, ptr %src, i64 %idx.ext
36175d68ddSFlorian Hahn  br i1 %cmp.idx, label %then, label %else
37175d68ddSFlorian Hahn
38175d68ddSFlorian Hahnthen:
39*34e477e9SFlorian Hahn  call void @noundef(ptr %upper)
40*34e477e9SFlorian Hahn  %cmp.upper.1 = icmp ule ptr %src.idx, %upper
41175d68ddSFlorian Hahn  ret i1 %cmp.upper.1
42175d68ddSFlorian Hahn
43175d68ddSFlorian Hahnelse:
44*34e477e9SFlorian Hahn  %cmp.upper.2 = icmp ule ptr %src.idx, %upper
45175d68ddSFlorian Hahn  ret i1 %cmp.upper.2
46175d68ddSFlorian Hahn}
47175d68ddSFlorian Hahn
48*34e477e9SFlorian Hahndefine i1 @inbounds_poison_is_ub_in_use_block_2(ptr %src, i32 %n, i32 %idx, i1 %c) {
49175d68ddSFlorian Hahn; CHECK-LABEL: @inbounds_poison_is_ub_in_use_block_2(
50175d68ddSFlorian Hahn; CHECK-NEXT:  entry:
51175d68ddSFlorian Hahn; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64
52*34e477e9SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]]
53175d68ddSFlorian Hahn; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]]
54175d68ddSFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
55*34e477e9SFlorian Hahn; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]]
56175d68ddSFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]]
57175d68ddSFlorian Hahn; CHECK:       then:
58*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]
59*34e477e9SFlorian Hahn; CHECK-NEXT:    call void @noundef(ptr [[UPPER]])
60175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_UPPER_1]]
61175d68ddSFlorian Hahn; CHECK:       else:
62*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]
63175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_UPPER_2]]
64175d68ddSFlorian Hahn;
65175d68ddSFlorian Hahnentry:
66175d68ddSFlorian Hahn  %n.ext = zext i32 %n to i64
67*34e477e9SFlorian Hahn  %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext
68175d68ddSFlorian Hahn  %cmp.idx = icmp ult i32 %idx, %n
69175d68ddSFlorian Hahn  %idx.ext = zext i32 %idx to i64
70*34e477e9SFlorian Hahn  %src.idx = getelementptr i32, ptr %src, i64 %idx.ext
71175d68ddSFlorian Hahn  br i1 %cmp.idx, label %then, label %else
72175d68ddSFlorian Hahn
73175d68ddSFlorian Hahnthen:
74*34e477e9SFlorian Hahn  %cmp.upper.1 = icmp ule ptr %src.idx, %upper
75*34e477e9SFlorian Hahn  call void @noundef(ptr %upper)
76175d68ddSFlorian Hahn  ret i1 %cmp.upper.1
77175d68ddSFlorian Hahn
78175d68ddSFlorian Hahnelse:
79*34e477e9SFlorian Hahn  %cmp.upper.2 = icmp ule ptr %src.idx, %upper
80175d68ddSFlorian Hahn  ret i1 %cmp.upper.2
81175d68ddSFlorian Hahn}
82175d68ddSFlorian Hahn
83175d68ddSFlorian Hahndeclare void @llvm.assume(i1)
84175d68ddSFlorian Hahn
85175d68ddSFlorian Hahn; %start + %n.ext is guaranteed to not overflow (due to inbounds).
86175d68ddSFlorian Hahn; %start + %idx.ext does not overflow if %idx.ext <= %n.ext.
87*34e477e9SFlorian Hahndefine i1 @inbounds_poison_is_ub_in_use_block_by_assume(ptr %src, i32 %n, i32 %idx) {
88175d68ddSFlorian Hahn; CHECK-LABEL: @inbounds_poison_is_ub_in_use_block_by_assume(
89175d68ddSFlorian Hahn; CHECK-NEXT:  entry:
90175d68ddSFlorian Hahn; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64
91*34e477e9SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]]
92175d68ddSFlorian Hahn; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]]
93175d68ddSFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
94*34e477e9SFlorian Hahn; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]]
95175d68ddSFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]]
96175d68ddSFlorian Hahn; CHECK:       then:
97*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_NE:%.*]] = icmp ule ptr null, [[UPPER]]
98175d68ddSFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_NE]])
99*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]
100175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_UPPER_1]]
101175d68ddSFlorian Hahn; CHECK:       else:
102*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]
103175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_UPPER_2]]
104175d68ddSFlorian Hahn;
105175d68ddSFlorian Hahnentry:
106175d68ddSFlorian Hahn  %n.ext = zext i32 %n to i64
107*34e477e9SFlorian Hahn  %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext
108175d68ddSFlorian Hahn  %cmp.idx = icmp ult i32 %idx, %n
109175d68ddSFlorian Hahn  %idx.ext = zext i32 %idx to i64
110*34e477e9SFlorian Hahn  %src.idx = getelementptr i32, ptr %src, i64 %idx.ext
111175d68ddSFlorian Hahn  br i1 %cmp.idx, label %then, label %else
112175d68ddSFlorian Hahn
113175d68ddSFlorian Hahnthen:
114*34e477e9SFlorian Hahn  %cmp.ne = icmp ule ptr null, %upper
115175d68ddSFlorian Hahn  call void @llvm.assume(i1 %cmp.ne)
116*34e477e9SFlorian Hahn  %cmp.upper.1 = icmp ule ptr %src.idx, %upper
117175d68ddSFlorian Hahn  ret i1 %cmp.upper.1
118175d68ddSFlorian Hahn
119175d68ddSFlorian Hahnelse:
120*34e477e9SFlorian Hahn  %cmp.upper.2 = icmp ule ptr %src.idx, %upper
121175d68ddSFlorian Hahn  ret i1 %cmp.upper.2
122175d68ddSFlorian Hahn}
123175d68ddSFlorian Hahn
124175d68ddSFlorian Hahn
125175d68ddSFlorian Hahn; %start + %n.ext is guaranteed to not overflow (due to inbounds).
126175d68ddSFlorian Hahn; %start + %idx.ext does not overflow if %idx.ext <= %n.ext.
127*34e477e9SFlorian Hahndefine i1 @inbounds_poison_is_ub_in_in_multiple_use_blocks_1(ptr %src, i32 %n, i32 %idx, i1 %c) {
128175d68ddSFlorian Hahn; CHECK-LABEL: @inbounds_poison_is_ub_in_in_multiple_use_blocks_1(
129175d68ddSFlorian Hahn; CHECK-NEXT:  entry:
130175d68ddSFlorian Hahn; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64
131*34e477e9SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]]
132175d68ddSFlorian Hahn; CHECK-NEXT:    br i1 [[C:%.*]], label [[CHECK_BB:%.*]], label [[EXIT:%.*]]
133175d68ddSFlorian Hahn; CHECK:       check.bb:
134*34e477e9SFlorian Hahn; CHECK-NEXT:    call void @noundef(ptr [[UPPER]])
135175d68ddSFlorian Hahn; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]]
136175d68ddSFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
137*34e477e9SFlorian Hahn; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]]
138175d68ddSFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]]
139175d68ddSFlorian Hahn; CHECK:       then:
140*34e477e9SFlorian Hahn; CHECK-NEXT:    call void @noundef(ptr [[UPPER]])
141*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]
142175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_UPPER_1]]
143175d68ddSFlorian Hahn; CHECK:       else:
144*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]
145175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_UPPER_2]]
146175d68ddSFlorian Hahn; CHECK:       exit:
147175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 false
148175d68ddSFlorian Hahn;
149175d68ddSFlorian Hahnentry:
150175d68ddSFlorian Hahn  %n.ext = zext i32 %n to i64
151*34e477e9SFlorian Hahn  %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext
152175d68ddSFlorian Hahn  br i1 %c, label %check.bb, label %exit
153175d68ddSFlorian Hahn
154175d68ddSFlorian Hahncheck.bb:
155*34e477e9SFlorian Hahn  call void @noundef(ptr %upper)
156175d68ddSFlorian Hahn  %cmp.idx = icmp ult i32 %idx, %n
157175d68ddSFlorian Hahn  %idx.ext = zext i32 %idx to i64
158*34e477e9SFlorian Hahn  %src.idx = getelementptr i32, ptr %src, i64 %idx.ext
159175d68ddSFlorian Hahn  br i1 %cmp.idx, label %then, label %else
160175d68ddSFlorian Hahn
161175d68ddSFlorian Hahnthen:
162*34e477e9SFlorian Hahn  call void @noundef(ptr %upper)
163*34e477e9SFlorian Hahn  %cmp.upper.1 = icmp ule ptr %src.idx, %upper
164175d68ddSFlorian Hahn  ret i1 %cmp.upper.1
165175d68ddSFlorian Hahn
166175d68ddSFlorian Hahnelse:
167*34e477e9SFlorian Hahn  %cmp.upper.2 = icmp ule ptr %src.idx, %upper
168175d68ddSFlorian Hahn  ret i1 %cmp.upper.2
169175d68ddSFlorian Hahn
170175d68ddSFlorian Hahnexit:
171175d68ddSFlorian Hahn  ret i1 false
172175d68ddSFlorian Hahn}
173175d68ddSFlorian Hahn
174*34e477e9SFlorian Hahndefine i1 @may_exit_before_ub_is_caused(ptr %src, i32 %n, i32 %idx) {
175175d68ddSFlorian Hahn; CHECK-LABEL: @may_exit_before_ub_is_caused(
176175d68ddSFlorian Hahn; CHECK-NEXT:  entry:
177175d68ddSFlorian Hahn; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64
178*34e477e9SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]]
179175d68ddSFlorian Hahn; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]]
180175d68ddSFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
181*34e477e9SFlorian Hahn; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]]
182175d68ddSFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]]
183175d68ddSFlorian Hahn; CHECK:       then:
184*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]
185175d68ddSFlorian Hahn; CHECK-NEXT:    call void @use(i1 [[CMP_UPPER_1]])
186*34e477e9SFlorian Hahn; CHECK-NEXT:    call void @noundef(ptr [[UPPER]])
187175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_UPPER_1]]
188175d68ddSFlorian Hahn; CHECK:       else:
189*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]
190175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_UPPER_2]]
191175d68ddSFlorian Hahn;
192175d68ddSFlorian Hahnentry:
193175d68ddSFlorian Hahn  %n.ext = zext i32 %n to i64
194*34e477e9SFlorian Hahn  %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext
195175d68ddSFlorian Hahn  %cmp.idx = icmp ult i32 %idx, %n
196175d68ddSFlorian Hahn  %idx.ext = zext i32 %idx to i64
197*34e477e9SFlorian Hahn  %src.idx = getelementptr i32, ptr %src, i64 %idx.ext
198175d68ddSFlorian Hahn  br i1 %cmp.idx, label %then, label %else
199175d68ddSFlorian Hahn
200175d68ddSFlorian Hahnthen:
201*34e477e9SFlorian Hahn  %cmp.upper.1 = icmp ule ptr %src.idx, %upper
202175d68ddSFlorian Hahn  call void @use(i1 %cmp.upper.1);
203*34e477e9SFlorian Hahn  call void @noundef(ptr %upper)
204175d68ddSFlorian Hahn  ret i1 %cmp.upper.1
205175d68ddSFlorian Hahn
206175d68ddSFlorian Hahnelse:
207*34e477e9SFlorian Hahn  %cmp.upper.2 = icmp ule ptr %src.idx, %upper
208175d68ddSFlorian Hahn  ret i1 %cmp.upper.2
209175d68ddSFlorian Hahn}
210175d68ddSFlorian Hahn
211*34e477e9SFlorian Hahndefine i1 @only_UB_in_false_block(ptr %src, i32 %n, i32 %idx) {
212175d68ddSFlorian Hahn; CHECK-LABEL: @only_UB_in_false_block(
213175d68ddSFlorian Hahn; CHECK-NEXT:  entry:
214175d68ddSFlorian Hahn; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64
215*34e477e9SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]]
216175d68ddSFlorian Hahn; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]]
217175d68ddSFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
218*34e477e9SFlorian Hahn; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]]
219175d68ddSFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]]
220175d68ddSFlorian Hahn; CHECK:       then:
221*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]
222175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_UPPER_1]]
223175d68ddSFlorian Hahn; CHECK:       else:
224*34e477e9SFlorian Hahn; CHECK-NEXT:    call void @noundef(ptr [[UPPER]])
225*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]
226175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_UPPER_2]]
227175d68ddSFlorian Hahn;
228175d68ddSFlorian Hahnentry:
229175d68ddSFlorian Hahn  %n.ext = zext i32 %n to i64
230*34e477e9SFlorian Hahn  %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext
231175d68ddSFlorian Hahn  %cmp.idx = icmp ult i32 %idx, %n
232175d68ddSFlorian Hahn  %idx.ext = zext i32 %idx to i64
233*34e477e9SFlorian Hahn  %src.idx = getelementptr i32, ptr %src, i64 %idx.ext
234175d68ddSFlorian Hahn  br i1 %cmp.idx, label %then, label %else
235175d68ddSFlorian Hahn
236175d68ddSFlorian Hahnthen:
237*34e477e9SFlorian Hahn  %cmp.upper.1 = icmp ule ptr %src.idx, %upper
238175d68ddSFlorian Hahn  ret i1 %cmp.upper.1
239175d68ddSFlorian Hahn
240175d68ddSFlorian Hahnelse:
241*34e477e9SFlorian Hahn  call void @noundef(ptr %upper)
242*34e477e9SFlorian Hahn  %cmp.upper.2 = icmp ule ptr %src.idx, %upper
243175d68ddSFlorian Hahn  ret i1 %cmp.upper.2
244175d68ddSFlorian Hahn}
245175d68ddSFlorian Hahn
246*34e477e9SFlorian Hahndefine i1 @only_ub_by_assume_in_false_block(ptr %src, i32 %n, i32 %idx) {
247175d68ddSFlorian Hahn; CHECK-LABEL: @only_ub_by_assume_in_false_block(
248175d68ddSFlorian Hahn; CHECK-NEXT:  entry:
249175d68ddSFlorian Hahn; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64
250*34e477e9SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]]
251175d68ddSFlorian Hahn; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]]
252175d68ddSFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64
253*34e477e9SFlorian Hahn; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]]
254175d68ddSFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]]
255175d68ddSFlorian Hahn; CHECK:       then:
256*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]
257175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_UPPER_1]]
258175d68ddSFlorian Hahn; CHECK:       else:
259*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_NE:%.*]] = icmp ule ptr null, [[UPPER]]
260175d68ddSFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_NE]])
261*34e477e9SFlorian Hahn; CHECK-NEXT:    [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]
262175d68ddSFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_UPPER_2]]
263175d68ddSFlorian Hahn;
264175d68ddSFlorian Hahnentry:
265175d68ddSFlorian Hahn  %n.ext = zext i32 %n to i64
266*34e477e9SFlorian Hahn  %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext
267175d68ddSFlorian Hahn  %cmp.idx = icmp ult i32 %idx, %n
268175d68ddSFlorian Hahn  %idx.ext = zext i32 %idx to i64
269*34e477e9SFlorian Hahn  %src.idx = getelementptr i32, ptr %src, i64 %idx.ext
270175d68ddSFlorian Hahn  br i1 %cmp.idx, label %then, label %else
271175d68ddSFlorian Hahn
272175d68ddSFlorian Hahnthen:
273*34e477e9SFlorian Hahn  %cmp.upper.1 = icmp ule ptr %src.idx, %upper
274175d68ddSFlorian Hahn  ret i1 %cmp.upper.1
275175d68ddSFlorian Hahn
276175d68ddSFlorian Hahnelse:
277*34e477e9SFlorian Hahn  %cmp.ne = icmp ule ptr null, %upper
278175d68ddSFlorian Hahn  call void @llvm.assume(i1 %cmp.ne)
279*34e477e9SFlorian Hahn  %cmp.upper.2 = icmp ule ptr %src.idx, %upper
280175d68ddSFlorian Hahn  ret i1 %cmp.upper.2
281175d68ddSFlorian Hahn}
282