1*6b1396e3SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2*6b1396e3SFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3*6b1396e3SFlorian Hahn
4*6b1396e3SFlorian Hahndeclare void @llvm.assume(i1 noundef) #0
5*6b1396e3SFlorian Hahn
6*6b1396e3SFlorian Hahndefine i1 @n_unknown(ptr %dst, i32 %n, i32 %i) {
7*6b1396e3SFlorian Hahn; CHECK-LABEL: @n_unknown(
8*6b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
9*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[N:%.*]], -1
10*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[SUB]] to i64
11*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[PTR_N_SUB_1:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 [[IDXPROM]]
12*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_PTR_DST:%.*]] = icmp sge ptr [[PTR_N_SUB_1]], [[DST]]
13*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_PTR_DST]], label [[PRE_BB_2:%.*]], label [[EXIT:%.*]]
14*6b1396e3SFlorian Hahn; CHECK:       exit:
15*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i1 false
16*6b1396e3SFlorian Hahn; CHECK:       pre.bb.2:
17*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[PRE_2:%.*]] = icmp sge i32 [[I:%.*]], 0
18*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[PRE_2]], label [[TGT_BB:%.*]], label [[EXIT]]
19*6b1396e3SFlorian Hahn; CHECK:       tgt.bb:
20*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[I]], [[N]]
21*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP1]]
22*6b1396e3SFlorian Hahn;
23*6b1396e3SFlorian Hahnentry:
24*6b1396e3SFlorian Hahn  %sub = add i32 %n, -1
25*6b1396e3SFlorian Hahn  %idxprom = zext i32 %sub to i64
26*6b1396e3SFlorian Hahn  %ptr.n.sub.1 = getelementptr i32, ptr %dst, i64 %idxprom
27*6b1396e3SFlorian Hahn  %cmp.ptr.dst = icmp sge ptr %ptr.n.sub.1, %dst
28*6b1396e3SFlorian Hahn  br i1 %cmp.ptr.dst, label %pre.bb.2, label %exit
29*6b1396e3SFlorian Hahn
30*6b1396e3SFlorian Hahnexit:
31*6b1396e3SFlorian Hahn  ret i1 false
32*6b1396e3SFlorian Hahn
33*6b1396e3SFlorian Hahnpre.bb.2:
34*6b1396e3SFlorian Hahn  %pre.2 = icmp sge i32 %i, 0
35*6b1396e3SFlorian Hahn  br i1 %pre.2, label %tgt.bb, label %exit
36*6b1396e3SFlorian Hahn
37*6b1396e3SFlorian Hahntgt.bb:
38*6b1396e3SFlorian Hahn  %cmp1 = icmp slt i32 %i, %n
39*6b1396e3SFlorian Hahn  ret i1 %cmp1
40*6b1396e3SFlorian Hahn}
41*6b1396e3SFlorian Hahn
42*6b1396e3SFlorian Hahndefine i1 @n_known_zero_due_to_nuw(ptr %dst, i32 %n, i32 %i) {
43*6b1396e3SFlorian Hahn; CHECK-LABEL: @n_known_zero_due_to_nuw(
44*6b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
45*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[N:%.*]], -1
46*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[SUB]] to i64
47*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[PTR_N_SUB_1:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 [[IDXPROM]]
48*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_PTR_DST:%.*]] = icmp sge ptr [[PTR_N_SUB_1]], [[DST]]
49*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_PTR_DST]], label [[PRE_BB_2:%.*]], label [[EXIT:%.*]]
50*6b1396e3SFlorian Hahn; CHECK:       exit:
51*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i1 false
52*6b1396e3SFlorian Hahn; CHECK:       pre.bb.2:
53*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[PRE_2:%.*]] = icmp sge i32 [[I:%.*]], 0
54*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[PRE_2]], label [[TGT_BB:%.*]], label [[EXIT]]
55*6b1396e3SFlorian Hahn; CHECK:       tgt.bb:
56*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[I]], [[N]]
57*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP1]]
58*6b1396e3SFlorian Hahn;
59*6b1396e3SFlorian Hahnentry:
60*6b1396e3SFlorian Hahn  %sub = add i32 %n, -1
61*6b1396e3SFlorian Hahn  %idxprom = zext i32 %sub to i64
62*6b1396e3SFlorian Hahn  %ptr.n.sub.1 = getelementptr i32, ptr %dst, i64 %idxprom
63*6b1396e3SFlorian Hahn  %cmp.ptr.dst = icmp sge ptr %ptr.n.sub.1, %dst
64*6b1396e3SFlorian Hahn  br i1 %cmp.ptr.dst, label %pre.bb.2, label %exit
65*6b1396e3SFlorian Hahn
66*6b1396e3SFlorian Hahnexit:
67*6b1396e3SFlorian Hahn  ret i1 false
68*6b1396e3SFlorian Hahn
69*6b1396e3SFlorian Hahnpre.bb.2:
70*6b1396e3SFlorian Hahn  %pre.2 = icmp sge i32 %i, 0
71*6b1396e3SFlorian Hahn  br i1 %pre.2, label %tgt.bb, label %exit
72*6b1396e3SFlorian Hahn
73*6b1396e3SFlorian Hahntgt.bb:
74*6b1396e3SFlorian Hahn  %cmp1 = icmp slt i32 %i, %n
75*6b1396e3SFlorian Hahn  ret i1 %cmp1
76*6b1396e3SFlorian Hahn}
77*6b1396e3SFlorian Hahn
78*6b1396e3SFlorian Hahndefine i4 @inc_ptr_N_could_be_negative(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) {
79*6b1396e3SFlorian Hahn; CHECK-LABEL: @inc_ptr_N_could_be_negative(
80*6b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
81*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]
82*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
83*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
84*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
85*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
86*6b1396e3SFlorian Hahn; CHECK:       trap.bb:
87*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
88*6b1396e3SFlorian Hahn; CHECK:       step.check:
89*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i8 [[STEP:%.*]], 0
90*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[NEXT:%.*]] = add nuw nsw i8 [[STEP]], 2
91*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i8 [[NEXT]], [[N]]
92*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]
93*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
94*6b1396e3SFlorian Hahn; CHECK:       ptr.check:
95*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]]
96*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
97*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
98*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
99*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
100*6b1396e3SFlorian Hahn; CHECK:       exit:
101*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
102*6b1396e3SFlorian Hahn;
103*6b1396e3SFlorian Hahnentry:
104*6b1396e3SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i8 %N
105*6b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src, %lower
106*6b1396e3SFlorian Hahn  %cmp.src.end = icmp sge ptr %src.end, %upper
107*6b1396e3SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
108*6b1396e3SFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
109*6b1396e3SFlorian Hahn
110*6b1396e3SFlorian Hahntrap.bb:
111*6b1396e3SFlorian Hahn  ret i4 2
112*6b1396e3SFlorian Hahn
113*6b1396e3SFlorian Hahnstep.check:
114*6b1396e3SFlorian Hahn  %step.pos = icmp sge i8 %step, 0
115*6b1396e3SFlorian Hahn  %next = add nuw nsw i8 %step, 2
116*6b1396e3SFlorian Hahn  %step.slt.N = icmp slt i8 %next, %N
117*6b1396e3SFlorian Hahn  %and.step = and i1 %step.pos, %step.slt.N
118*6b1396e3SFlorian Hahn  br i1 %and.step, label %ptr.check, label %exit
119*6b1396e3SFlorian Hahn
120*6b1396e3SFlorian Hahnptr.check:
121*6b1396e3SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i8 %step
122*6b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
123*6b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
124*6b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
125*6b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
126*6b1396e3SFlorian Hahn
127*6b1396e3SFlorian Hahnexit:
128*6b1396e3SFlorian Hahn  ret i4 3
129*6b1396e3SFlorian Hahn}
130*6b1396e3SFlorian Hahn
131*6b1396e3SFlorian Hahndefine i4 @inc_ptr_src_sge_end(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
132*6b1396e3SFlorian Hahn; CHECK-LABEL: @inc_ptr_src_sge_end(
133*6b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
134*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
135*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
136*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
137*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_OVERFLOW:%.*]] = icmp sgt ptr [[SRC]], [[SRC_END]]
138*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
139*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[CMP_OVERFLOW]]
140*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
141*6b1396e3SFlorian Hahn; CHECK:       trap.bb:
142*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
143*6b1396e3SFlorian Hahn; CHECK:       step.check:
144*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0
145*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[NEXT:%.*]] = add nuw nsw i16 [[STEP]], 2
146*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 [[NEXT]], [[N]]
147*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]
148*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
149*6b1396e3SFlorian Hahn; CHECK:       ptr.check:
150*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
151*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
152*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
153*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
154*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
155*6b1396e3SFlorian Hahn; CHECK:       exit:
156*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
157*6b1396e3SFlorian Hahn;
158*6b1396e3SFlorian Hahnentry:
159*6b1396e3SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i16 %N
160*6b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src, %lower
161*6b1396e3SFlorian Hahn  %cmp.src.end = icmp sge ptr %src.end, %upper
162*6b1396e3SFlorian Hahn  %cmp.overflow = icmp sgt ptr %src, %src.end
163*6b1396e3SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
164*6b1396e3SFlorian Hahn  %or.precond.1 = or i1 %or.precond.0, %cmp.overflow
165*6b1396e3SFlorian Hahn  br i1 %or.precond.1, label %trap.bb, label %step.check
166*6b1396e3SFlorian Hahn
167*6b1396e3SFlorian Hahntrap.bb:
168*6b1396e3SFlorian Hahn  ret i4 2
169*6b1396e3SFlorian Hahn
170*6b1396e3SFlorian Hahnstep.check:
171*6b1396e3SFlorian Hahn  %step.pos = icmp sge i16 %step, 0
172*6b1396e3SFlorian Hahn  %next = add nuw nsw i16 %step, 2
173*6b1396e3SFlorian Hahn  %step.slt.N = icmp slt i16 %next, %N
174*6b1396e3SFlorian Hahn  %and.step = and i1 %step.pos, %step.slt.N
175*6b1396e3SFlorian Hahn  br i1 %and.step, label %ptr.check, label %exit
176*6b1396e3SFlorian Hahn
177*6b1396e3SFlorian Hahnptr.check:
178*6b1396e3SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 %step
179*6b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
180*6b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
181*6b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
182*6b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
183*6b1396e3SFlorian Hahn
184*6b1396e3SFlorian Hahnexit:
185*6b1396e3SFlorian Hahn  ret i4 3
186*6b1396e3SFlorian Hahn}
187*6b1396e3SFlorian Hahn
188*6b1396e3SFlorian Hahndefine i4 @inc_ptr_src_sge_end_no_nsw_add(ptr %src, ptr %lower, ptr %upper, i16 %idx, i16 %N, i16 %step) {
189*6b1396e3SFlorian Hahn; CHECK-LABEL: @inc_ptr_src_sge_end_no_nsw_add(
190*6b1396e3SFlorian Hahn; CHECK-NEXT:  entry.1:
191*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[IDX_POS:%.*]] = icmp sge i16 [[IDX:%.*]], 0
192*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[IDX_POS]], label [[ENTRY:%.*]], label [[TRAP_BB:%.*]]
193*6b1396e3SFlorian Hahn; CHECK:       entry:
194*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[IDX]]
195*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC_IDX]], [[LOWER:%.*]]
196*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_SRC_START]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
197*6b1396e3SFlorian Hahn; CHECK:       trap.bb:
198*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
199*6b1396e3SFlorian Hahn; CHECK:       step.check:
200*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[NEXT:%.*]] = add i16 [[IDX]], 2
201*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[NEXT]]
202*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
203*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER:%.*]]
204*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
205*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT:%.*]]
206*6b1396e3SFlorian Hahn; CHECK:       exit:
207*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
208*6b1396e3SFlorian Hahn;
209*6b1396e3SFlorian Hahnentry.1:
210*6b1396e3SFlorian Hahn  %idx.pos = icmp sge i16 %idx, 0
211*6b1396e3SFlorian Hahn  br i1 %idx.pos, label %entry, label %trap.bb
212*6b1396e3SFlorian Hahn
213*6b1396e3SFlorian Hahnentry:
214*6b1396e3SFlorian Hahn  %src.idx = getelementptr inbounds i8, ptr %src, i16 %idx
215*6b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src.idx, %lower
216*6b1396e3SFlorian Hahn  br i1 %cmp.src.start, label %trap.bb, label %step.check
217*6b1396e3SFlorian Hahn
218*6b1396e3SFlorian Hahntrap.bb:
219*6b1396e3SFlorian Hahn  ret i4 2
220*6b1396e3SFlorian Hahn
221*6b1396e3SFlorian Hahnstep.check:
222*6b1396e3SFlorian Hahn  %next = add i16 %idx, 2
223*6b1396e3SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 %next
224*6b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
225*6b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
226*6b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
227*6b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
228*6b1396e3SFlorian Hahn
229*6b1396e3SFlorian Hahnexit:
230*6b1396e3SFlorian Hahn  ret i4 3
231*6b1396e3SFlorian Hahn}
232*6b1396e3SFlorian Hahn
233*6b1396e3SFlorian Hahndefine i4 @inc_ptr_src_sge_end_no_nsw_add_sge_0(ptr %src, ptr %lower, ptr %upper, i16 %idx, i16 %N, i16 %step) {
234*6b1396e3SFlorian Hahn; CHECK-LABEL: @inc_ptr_src_sge_end_no_nsw_add_sge_0(
235*6b1396e3SFlorian Hahn; CHECK-NEXT:  entry.1:
236*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[IDX_POS:%.*]] = icmp sge i16 [[IDX:%.*]], 0
237*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[IDX_POS]], label [[ENTRY:%.*]], label [[TRAP_BB:%.*]]
238*6b1396e3SFlorian Hahn; CHECK:       entry:
239*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[IDX]]
240*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC_IDX]], [[LOWER:%.*]]
241*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_SRC_START]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
242*6b1396e3SFlorian Hahn; CHECK:       trap.bb:
243*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
244*6b1396e3SFlorian Hahn; CHECK:       step.check:
245*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[NEXT:%.*]] = add i16 [[IDX]], 2
246*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[NEXT]]
247*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
248*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER:%.*]]
249*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
250*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT:%.*]]
251*6b1396e3SFlorian Hahn; CHECK:       exit:
252*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
253*6b1396e3SFlorian Hahn;
254*6b1396e3SFlorian Hahnentry.1:
255*6b1396e3SFlorian Hahn  %idx.pos = icmp sge i16 %idx, 0
256*6b1396e3SFlorian Hahn  br i1 %idx.pos, label %entry, label %trap.bb
257*6b1396e3SFlorian Hahn
258*6b1396e3SFlorian Hahnentry:
259*6b1396e3SFlorian Hahn  %src.idx = getelementptr inbounds i8, ptr %src, i16 %idx
260*6b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src.idx, %lower
261*6b1396e3SFlorian Hahn  br i1 %cmp.src.start, label %trap.bb, label %step.check
262*6b1396e3SFlorian Hahn
263*6b1396e3SFlorian Hahntrap.bb:
264*6b1396e3SFlorian Hahn  ret i4 2
265*6b1396e3SFlorian Hahn
266*6b1396e3SFlorian Hahnstep.check:
267*6b1396e3SFlorian Hahn  %next = add i16 %idx, 2
268*6b1396e3SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 %next
269*6b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
270*6b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
271*6b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
272*6b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
273*6b1396e3SFlorian Hahn
274*6b1396e3SFlorian Hahnexit:
275*6b1396e3SFlorian Hahn  ret i4 3
276*6b1396e3SFlorian Hahn}
277*6b1396e3SFlorian Hahndefine i4 @ptr_N_step_zext_n_zext(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
278*6b1396e3SFlorian Hahn; CHECK-LABEL: @ptr_N_step_zext_n_zext(
279*6b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
280*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[N_ADD_1:%.*]] = add nuw nsw i16 [[N:%.*]], 1
281*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[N_ADD_1_EXT:%.*]] = zext i16 [[N_ADD_1]] to i32
282*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i32 [[N_ADD_1_EXT]]
283*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
284*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
285*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
286*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
287*6b1396e3SFlorian Hahn; CHECK:       trap.bb:
288*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
289*6b1396e3SFlorian Hahn; CHECK:       step.check:
290*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_ADD_1:%.*]] = add nuw nsw i16 [[STEP:%.*]], 1
291*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_ADD_1_EXT:%.*]] = zext i16 [[STEP_ADD_1]] to i32
292*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i32 [[STEP_ADD_1_EXT]], [[N_ADD_1_EXT]]
293*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[STEP_SLT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
294*6b1396e3SFlorian Hahn; CHECK:       ptr.check:
295*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i32 [[STEP_ADD_1_EXT]]
296*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
297*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
298*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
299*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
300*6b1396e3SFlorian Hahn; CHECK:       exit:
301*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
302*6b1396e3SFlorian Hahn;
303*6b1396e3SFlorian Hahnentry:
304*6b1396e3SFlorian Hahn  %N.add.1 = add nuw nsw i16 %N, 1
305*6b1396e3SFlorian Hahn  %N.add.1.ext = zext i16 %N.add.1 to i32
306*6b1396e3SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i32 %N.add.1.ext
307*6b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src, %lower
308*6b1396e3SFlorian Hahn  %cmp.src.end = icmp sge ptr %src.end, %upper
309*6b1396e3SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
310*6b1396e3SFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
311*6b1396e3SFlorian Hahn
312*6b1396e3SFlorian Hahntrap.bb:
313*6b1396e3SFlorian Hahn  ret i4 2
314*6b1396e3SFlorian Hahn
315*6b1396e3SFlorian Hahnstep.check:
316*6b1396e3SFlorian Hahn  %step.add.1 = add nuw nsw i16 %step, 1
317*6b1396e3SFlorian Hahn  %step.add.1.ext = zext i16 %step.add.1 to i32
318*6b1396e3SFlorian Hahn  %step.slt.N = icmp slt i32 %step.add.1.ext, %N.add.1.ext
319*6b1396e3SFlorian Hahn  br i1 %step.slt.N, label %ptr.check, label %exit
320*6b1396e3SFlorian Hahn
321*6b1396e3SFlorian Hahnptr.check:
322*6b1396e3SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i32 %step.add.1.ext
323*6b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
324*6b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
325*6b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
326*6b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
327*6b1396e3SFlorian Hahn
328*6b1396e3SFlorian Hahnexit:
329*6b1396e3SFlorian Hahn  ret i4 3
330*6b1396e3SFlorian Hahn}
331*6b1396e3SFlorian Hahn
332*6b1396e3SFlorian Hahndefine i4 @ptr_N_step_zext_n_zext_out_of_bounds(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
333*6b1396e3SFlorian Hahn; CHECK-LABEL: @ptr_N_step_zext_n_zext_out_of_bounds(
334*6b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
335*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[N_ADD_2:%.*]] = add nuw nsw i16 [[N:%.*]], 2
336*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[N_ADD_2_EXT:%.*]] = zext i16 [[N_ADD_2]] to i32
337*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i32 [[N_ADD_2_EXT]]
338*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
339*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
340*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
341*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
342*6b1396e3SFlorian Hahn; CHECK:       trap.bb:
343*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
344*6b1396e3SFlorian Hahn; CHECK:       step.check:
345*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_ADD_2:%.*]] = add nuw nsw i16 [[STEP:%.*]], 2
346*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_ADD_2_EXT:%.*]] = zext i16 [[STEP_ADD_2]] to i32
347*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_EXT:%.*]] = zext i16 [[STEP]] to i32
348*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i32 [[STEP_EXT]], [[N_ADD_2_EXT]]
349*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[STEP_SLT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
350*6b1396e3SFlorian Hahn; CHECK:       ptr.check:
351*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i32 [[STEP_ADD_2_EXT]]
352*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
353*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
354*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
355*6b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
356*6b1396e3SFlorian Hahn; CHECK:       exit:
357*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
358*6b1396e3SFlorian Hahn;
359*6b1396e3SFlorian Hahnentry:
360*6b1396e3SFlorian Hahn  %N.add.2 = add nuw nsw i16 %N, 2
361*6b1396e3SFlorian Hahn  %N.add.2.ext = zext i16 %N.add.2 to i32
362*6b1396e3SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i32 %N.add.2.ext
363*6b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src, %lower
364*6b1396e3SFlorian Hahn  %cmp.src.end = icmp sge ptr %src.end, %upper
365*6b1396e3SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
366*6b1396e3SFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
367*6b1396e3SFlorian Hahn
368*6b1396e3SFlorian Hahntrap.bb:
369*6b1396e3SFlorian Hahn  ret i4 2
370*6b1396e3SFlorian Hahn
371*6b1396e3SFlorian Hahnstep.check:
372*6b1396e3SFlorian Hahn  %step.add.2 = add nuw nsw i16 %step, 2
373*6b1396e3SFlorian Hahn  %step.add.2.ext = zext i16 %step.add.2 to i32
374*6b1396e3SFlorian Hahn  %step.ext = zext i16 %step to i32
375*6b1396e3SFlorian Hahn  %step.slt.N = icmp slt i32 %step.ext, %N.add.2.ext
376*6b1396e3SFlorian Hahn  br i1 %step.slt.N, label %ptr.check, label %exit
377*6b1396e3SFlorian Hahn
378*6b1396e3SFlorian Hahnptr.check:
379*6b1396e3SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i32 %step.add.2.ext
380*6b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
381*6b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
382*6b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
383*6b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
384*6b1396e3SFlorian Hahn
385*6b1396e3SFlorian Hahnexit:
386*6b1396e3SFlorian Hahn  ret i4 3
387*6b1396e3SFlorian Hahn}
388*6b1396e3SFlorian Hahn
389*6b1396e3SFlorian Hahndefine i1 @gep_count_add_1_sge_known_slt_1(i32 %count, ptr %p) {
390*6b1396e3SFlorian Hahn; CHECK-LABEL: @gep_count_add_1_sge_known_slt_1(
391*6b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
392*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
393*6b1396e3SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
394*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
395*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
396*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -1
397*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
398*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
399*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp slt ptr [[GEP_SUB]], [[GEP_COUNT]]
400*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i1 [[C]]
401*6b1396e3SFlorian Hahn;
402*6b1396e3SFlorian Hahnentry:
403*6b1396e3SFlorian Hahn  %sge = icmp sge i32 %count, 1
404*6b1396e3SFlorian Hahn  call void @llvm.assume(i1 %sge)
405*6b1396e3SFlorian Hahn  %count.ext = zext i32 %count to i64
406*6b1396e3SFlorian Hahn  %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
407*6b1396e3SFlorian Hahn  %sub = add nsw i32 %count, -1
408*6b1396e3SFlorian Hahn  %sub.ext = zext i32 %sub to i64
409*6b1396e3SFlorian Hahn  %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
410*6b1396e3SFlorian Hahn  %c = icmp slt ptr %gep.sub, %gep.count
411*6b1396e3SFlorian Hahn  ;%2 = icmp sge ptr %0, %p
412*6b1396e3SFlorian Hahn  ret i1 %c
413*6b1396e3SFlorian Hahn}
414*6b1396e3SFlorian Hahn
415*6b1396e3SFlorian Hahndefine i1 @gep_count_add_1_sge_known_sge_1(i32 %count, ptr %p) {
416*6b1396e3SFlorian Hahn; CHECK-LABEL: @gep_count_add_1_sge_known_sge_1(
417*6b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
418*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
419*6b1396e3SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
420*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
421*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
422*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -1
423*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
424*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
425*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp sge ptr [[GEP_SUB]], [[P]]
426*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i1 [[C]]
427*6b1396e3SFlorian Hahn;
428*6b1396e3SFlorian Hahnentry:
429*6b1396e3SFlorian Hahn  %sge = icmp sge i32 %count, 1
430*6b1396e3SFlorian Hahn  call void @llvm.assume(i1 %sge)
431*6b1396e3SFlorian Hahn  %count.ext = zext i32 %count to i64
432*6b1396e3SFlorian Hahn  %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
433*6b1396e3SFlorian Hahn  %sub = add nsw i32 %count, -1
434*6b1396e3SFlorian Hahn  %sub.ext = zext i32 %sub to i64
435*6b1396e3SFlorian Hahn  %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
436*6b1396e3SFlorian Hahn  %c = icmp sge ptr %gep.sub, %p
437*6b1396e3SFlorian Hahn  ret i1 %c
438*6b1396e3SFlorian Hahn}
439*6b1396e3SFlorian Hahn
440*6b1396e3SFlorian Hahndefine i1 @gep_count_add_2_sge_not_known_slt_1(i32 %count, ptr %p) {
441*6b1396e3SFlorian Hahn; CHECK-LABEL: @gep_count_add_2_sge_not_known_slt_1(
442*6b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
443*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
444*6b1396e3SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
445*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
446*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
447*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -2
448*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
449*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
450*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp slt ptr [[GEP_SUB]], [[GEP_COUNT]]
451*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i1 [[C]]
452*6b1396e3SFlorian Hahn;
453*6b1396e3SFlorian Hahnentry:
454*6b1396e3SFlorian Hahn  %sge = icmp sge i32 %count, 1
455*6b1396e3SFlorian Hahn  call void @llvm.assume(i1 %sge)
456*6b1396e3SFlorian Hahn  %count.ext = zext i32 %count to i64
457*6b1396e3SFlorian Hahn  %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
458*6b1396e3SFlorian Hahn  %sub = add nsw i32 %count, -2
459*6b1396e3SFlorian Hahn  %sub.ext = zext i32 %sub to i64
460*6b1396e3SFlorian Hahn  %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
461*6b1396e3SFlorian Hahn  %c = icmp slt ptr %gep.sub, %gep.count
462*6b1396e3SFlorian Hahn  ret i1 %c
463*6b1396e3SFlorian Hahn}
464*6b1396e3SFlorian Hahn
465*6b1396e3SFlorian Hahndefine i1 @gep_count_add_2_sge_not_known_sge_1(i32 %count, ptr %p) {
466*6b1396e3SFlorian Hahn; CHECK-LABEL: @gep_count_add_2_sge_not_known_sge_1(
467*6b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
468*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
469*6b1396e3SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
470*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
471*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
472*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -2
473*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
474*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
475*6b1396e3SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp sge ptr [[GEP_SUB]], [[P]]
476*6b1396e3SFlorian Hahn; CHECK-NEXT:    ret i1 [[C]]
477*6b1396e3SFlorian Hahn;
478*6b1396e3SFlorian Hahnentry:
479*6b1396e3SFlorian Hahn  %sge = icmp sge i32 %count, 1
480*6b1396e3SFlorian Hahn  call void @llvm.assume(i1 %sge)
481*6b1396e3SFlorian Hahn  %count.ext = zext i32 %count to i64
482*6b1396e3SFlorian Hahn  %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
483*6b1396e3SFlorian Hahn  %sub = add nsw i32 %count, -2
484*6b1396e3SFlorian Hahn  %sub.ext = zext i32 %sub to i64
485*6b1396e3SFlorian Hahn  %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
486*6b1396e3SFlorian Hahn  %c = icmp sge ptr %gep.sub, %p
487*6b1396e3SFlorian Hahn  ret i1 %c
488*6b1396e3SFlorian Hahn}
489