xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/gep-arithmetic-add.ll (revision fbcf8a8cbb2461730bfd0603b396842925a88ef2)
150a5e423SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
250a5e423SFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
350a5e423SFlorian Hahn
450a5e423SFlorian Hahndeclare void @llvm.assume(i1 noundef) #0
550a5e423SFlorian Hahn
650a5e423SFlorian Hahndefine i1 @n_unknown(ptr %dst, i32 %n, i32 %i) {
750a5e423SFlorian Hahn; CHECK-LABEL: @n_unknown(
850a5e423SFlorian Hahn; CHECK-NEXT:  entry:
950a5e423SFlorian Hahn; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[N:%.*]], -1
1050a5e423SFlorian Hahn; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[SUB]] to i64
1150a5e423SFlorian Hahn; CHECK-NEXT:    [[PTR_N_SUB_1:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 [[IDXPROM]]
1250a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_PTR_DST:%.*]] = icmp uge ptr [[PTR_N_SUB_1]], [[DST]]
1350a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_PTR_DST]], label [[PRE_BB_2:%.*]], label [[EXIT:%.*]]
1450a5e423SFlorian Hahn; CHECK:       exit:
1550a5e423SFlorian Hahn; CHECK-NEXT:    ret i1 false
1650a5e423SFlorian Hahn; CHECK:       pre.bb.2:
1798e016d9SFlorian Hahn; CHECK-NEXT:    br i1 true, label [[TGT_BB:%.*]], label [[EXIT]]
1850a5e423SFlorian Hahn; CHECK:       tgt.bb:
1998e016d9SFlorian Hahn; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I:%.*]], [[N]]
2050a5e423SFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP1]]
2150a5e423SFlorian Hahn;
2250a5e423SFlorian Hahnentry:
2350a5e423SFlorian Hahn  %sub = add i32 %n, -1
2450a5e423SFlorian Hahn  %idxprom = zext i32 %sub to i64
2550a5e423SFlorian Hahn  %ptr.n.sub.1 = getelementptr i32, ptr %dst, i64 %idxprom
2650a5e423SFlorian Hahn  %cmp.ptr.dst = icmp uge ptr %ptr.n.sub.1, %dst
2750a5e423SFlorian Hahn  br i1 %cmp.ptr.dst, label %pre.bb.2, label %exit
2850a5e423SFlorian Hahn
2950a5e423SFlorian Hahnexit:
3050a5e423SFlorian Hahn  ret i1 false
3150a5e423SFlorian Hahn
3250a5e423SFlorian Hahnpre.bb.2:
3350a5e423SFlorian Hahn  %pre.2 = icmp uge i32 %i, 0
3450a5e423SFlorian Hahn  br i1 %pre.2, label %tgt.bb, label %exit
3550a5e423SFlorian Hahn
3650a5e423SFlorian Hahntgt.bb:
3750a5e423SFlorian Hahn  %cmp1 = icmp ult i32 %i, %n
3850a5e423SFlorian Hahn  ret i1 %cmp1
3950a5e423SFlorian Hahn}
4050a5e423SFlorian Hahn
4150a5e423SFlorian Hahndefine i1 @n_known_zero_due_to_nuw(ptr %dst, i32 %n, i32 %i) {
4250a5e423SFlorian Hahn; CHECK-LABEL: @n_known_zero_due_to_nuw(
4350a5e423SFlorian Hahn; CHECK-NEXT:  entry:
4450a5e423SFlorian Hahn; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[N:%.*]], -1
4550a5e423SFlorian Hahn; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[SUB]] to i64
4650a5e423SFlorian Hahn; CHECK-NEXT:    [[PTR_N_SUB_1:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 [[IDXPROM]]
4750a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_PTR_DST:%.*]] = icmp uge ptr [[PTR_N_SUB_1]], [[DST]]
4850a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_PTR_DST]], label [[PRE_BB_2:%.*]], label [[EXIT:%.*]]
4950a5e423SFlorian Hahn; CHECK:       exit:
5050a5e423SFlorian Hahn; CHECK-NEXT:    ret i1 false
5150a5e423SFlorian Hahn; CHECK:       pre.bb.2:
5298e016d9SFlorian Hahn; CHECK-NEXT:    br i1 true, label [[TGT_BB:%.*]], label [[EXIT]]
5350a5e423SFlorian Hahn; CHECK:       tgt.bb:
5498e016d9SFlorian Hahn; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I:%.*]], [[N]]
5550a5e423SFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP1]]
5650a5e423SFlorian Hahn;
5750a5e423SFlorian Hahnentry:
5850a5e423SFlorian Hahn  %sub = add i32 %n, -1
5950a5e423SFlorian Hahn  %idxprom = zext i32 %sub to i64
6050a5e423SFlorian Hahn  %ptr.n.sub.1 = getelementptr i32, ptr %dst, i64 %idxprom
6150a5e423SFlorian Hahn  %cmp.ptr.dst = icmp uge ptr %ptr.n.sub.1, %dst
6250a5e423SFlorian Hahn  br i1 %cmp.ptr.dst, label %pre.bb.2, label %exit
6350a5e423SFlorian Hahn
6450a5e423SFlorian Hahnexit:
6550a5e423SFlorian Hahn  ret i1 false
6650a5e423SFlorian Hahn
6750a5e423SFlorian Hahnpre.bb.2:
6850a5e423SFlorian Hahn  %pre.2 = icmp uge i32 %i, 0
6950a5e423SFlorian Hahn  br i1 %pre.2, label %tgt.bb, label %exit
7050a5e423SFlorian Hahn
7150a5e423SFlorian Hahntgt.bb:
7250a5e423SFlorian Hahn  %cmp1 = icmp ult i32 %i, %n
7350a5e423SFlorian Hahn  ret i1 %cmp1
7450a5e423SFlorian Hahn}
7550a5e423SFlorian Hahn
7650a5e423SFlorian Hahndefine i4 @inc_ptr_N_could_be_negative(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) {
7750a5e423SFlorian Hahn; CHECK-LABEL: @inc_ptr_N_could_be_negative(
7850a5e423SFlorian Hahn; CHECK-NEXT:  entry:
7950a5e423SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]
8050a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
8150a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
8250a5e423SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
8350a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
8450a5e423SFlorian Hahn; CHECK:       trap.bb:
8550a5e423SFlorian Hahn; CHECK-NEXT:    ret i4 2
8650a5e423SFlorian Hahn; CHECK:       step.check:
8798e016d9SFlorian Hahn; CHECK-NEXT:    [[NEXT:%.*]] = add nuw nsw i8 [[STEP:%.*]], 2
8850a5e423SFlorian Hahn; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i8 [[NEXT]], [[N]]
8998e016d9SFlorian Hahn; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]]
9050a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
9150a5e423SFlorian Hahn; CHECK:       ptr.check:
9250a5e423SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]]
9350a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
9450a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
9550a5e423SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
9650a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
9750a5e423SFlorian Hahn; CHECK:       exit:
9850a5e423SFlorian Hahn; CHECK-NEXT:    ret i4 3
9950a5e423SFlorian Hahn;
10050a5e423SFlorian Hahnentry:
10150a5e423SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i8 %N
10250a5e423SFlorian Hahn  %cmp.src.start = icmp ult ptr %src, %lower
10350a5e423SFlorian Hahn  %cmp.src.end = icmp uge ptr %src.end, %upper
10450a5e423SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
10550a5e423SFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
10650a5e423SFlorian Hahn
10750a5e423SFlorian Hahntrap.bb:
10850a5e423SFlorian Hahn  ret i4 2
10950a5e423SFlorian Hahn
11050a5e423SFlorian Hahnstep.check:
11150a5e423SFlorian Hahn  %step.pos = icmp uge i8 %step, 0
11250a5e423SFlorian Hahn  %next = add nuw nsw i8 %step, 2
11350a5e423SFlorian Hahn  %step.ult.N = icmp ult i8 %next, %N
11450a5e423SFlorian Hahn  %and.step = and i1 %step.pos, %step.ult.N
11550a5e423SFlorian Hahn  br i1 %and.step, label %ptr.check, label %exit
11650a5e423SFlorian Hahn
11750a5e423SFlorian Hahnptr.check:
11850a5e423SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i8 %step
11950a5e423SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
12050a5e423SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
12150a5e423SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
12250a5e423SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
12350a5e423SFlorian Hahn
12450a5e423SFlorian Hahnexit:
12550a5e423SFlorian Hahn  ret i4 3
12650a5e423SFlorian Hahn}
12750a5e423SFlorian Hahn
12850a5e423SFlorian Hahndefine i4 @inc_ptr_src_uge_end(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
12950a5e423SFlorian Hahn; CHECK-LABEL: @inc_ptr_src_uge_end(
13050a5e423SFlorian Hahn; CHECK-NEXT:  entry:
13150a5e423SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
13250a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
13350a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
13450a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_OVERFLOW:%.*]] = icmp ugt ptr [[SRC]], [[SRC_END]]
13550a5e423SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
13650a5e423SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[CMP_OVERFLOW]]
13750a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
13850a5e423SFlorian Hahn; CHECK:       trap.bb:
13950a5e423SFlorian Hahn; CHECK-NEXT:    ret i4 2
14050a5e423SFlorian Hahn; CHECK:       step.check:
14198e016d9SFlorian Hahn; CHECK-NEXT:    [[NEXT:%.*]] = add nuw nsw i16 [[STEP:%.*]], 2
14250a5e423SFlorian Hahn; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i16 [[NEXT]], [[N]]
14398e016d9SFlorian Hahn; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]]
14450a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
14550a5e423SFlorian Hahn; CHECK:       ptr.check:
14650a5e423SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
14750a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
14850a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
14950a5e423SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
15050a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
15150a5e423SFlorian Hahn; CHECK:       exit:
15250a5e423SFlorian Hahn; CHECK-NEXT:    ret i4 3
15350a5e423SFlorian Hahn;
15450a5e423SFlorian Hahnentry:
15550a5e423SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i16 %N
15650a5e423SFlorian Hahn  %cmp.src.start = icmp ult ptr %src, %lower
15750a5e423SFlorian Hahn  %cmp.src.end = icmp uge ptr %src.end, %upper
15850a5e423SFlorian Hahn  %cmp.overflow = icmp ugt ptr %src, %src.end
15950a5e423SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
16050a5e423SFlorian Hahn  %or.precond.1 = or i1 %or.precond.0, %cmp.overflow
16150a5e423SFlorian Hahn  br i1 %or.precond.1, label %trap.bb, label %step.check
16250a5e423SFlorian Hahn
16350a5e423SFlorian Hahntrap.bb:
16450a5e423SFlorian Hahn  ret i4 2
16550a5e423SFlorian Hahn
16650a5e423SFlorian Hahnstep.check:
16750a5e423SFlorian Hahn  %step.pos = icmp uge i16 %step, 0
16850a5e423SFlorian Hahn  %next = add nuw nsw i16 %step, 2
16950a5e423SFlorian Hahn  %step.ult.N = icmp ult i16 %next, %N
17050a5e423SFlorian Hahn  %and.step = and i1 %step.pos, %step.ult.N
17150a5e423SFlorian Hahn  br i1 %and.step, label %ptr.check, label %exit
17250a5e423SFlorian Hahn
17350a5e423SFlorian Hahnptr.check:
17450a5e423SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 %step
17550a5e423SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
17650a5e423SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
17750a5e423SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
17850a5e423SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
17950a5e423SFlorian Hahn
18050a5e423SFlorian Hahnexit:
18150a5e423SFlorian Hahn  ret i4 3
18250a5e423SFlorian Hahn}
18350a5e423SFlorian Hahn
18450a5e423SFlorian Hahndefine i4 @inc_ptr_src_uge_end_no_nsw_add(ptr %src, ptr %lower, ptr %upper, i16 %idx, i16 %N, i16 %step) {
18550a5e423SFlorian Hahn; CHECK-LABEL: @inc_ptr_src_uge_end_no_nsw_add(
18650a5e423SFlorian Hahn; CHECK-NEXT:  entry.1:
18750a5e423SFlorian Hahn; CHECK-NEXT:    [[IDX_POS:%.*]] = icmp sge i16 [[IDX:%.*]], 0
18850a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[IDX_POS]], label [[ENTRY:%.*]], label [[TRAP_BB:%.*]]
18950a5e423SFlorian Hahn; CHECK:       entry:
19050a5e423SFlorian Hahn; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[IDX]]
19150a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC_IDX]], [[LOWER:%.*]]
19250a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_SRC_START]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
19350a5e423SFlorian Hahn; CHECK:       trap.bb:
19450a5e423SFlorian Hahn; CHECK-NEXT:    ret i4 2
19550a5e423SFlorian Hahn; CHECK:       step.check:
19650a5e423SFlorian Hahn; CHECK-NEXT:    [[NEXT:%.*]] = add i16 [[IDX]], 2
19750a5e423SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[NEXT]]
19850a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
19950a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER:%.*]]
20050a5e423SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
20150a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT:%.*]]
20250a5e423SFlorian Hahn; CHECK:       exit:
20350a5e423SFlorian Hahn; CHECK-NEXT:    ret i4 3
20450a5e423SFlorian Hahn;
20550a5e423SFlorian Hahnentry.1:
20650a5e423SFlorian Hahn  %idx.pos = icmp sge i16 %idx, 0
20750a5e423SFlorian Hahn  br i1 %idx.pos, label %entry, label %trap.bb
20850a5e423SFlorian Hahn
20950a5e423SFlorian Hahnentry:
21050a5e423SFlorian Hahn  %src.idx = getelementptr inbounds i8, ptr %src, i16 %idx
21150a5e423SFlorian Hahn  %cmp.src.start = icmp ult ptr %src.idx, %lower
21250a5e423SFlorian Hahn  br i1 %cmp.src.start, label %trap.bb, label %step.check
21350a5e423SFlorian Hahn
21450a5e423SFlorian Hahntrap.bb:
21550a5e423SFlorian Hahn  ret i4 2
21650a5e423SFlorian Hahn
21750a5e423SFlorian Hahnstep.check:
21850a5e423SFlorian Hahn  %next = add i16 %idx, 2
21950a5e423SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 %next
22050a5e423SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
22150a5e423SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
22250a5e423SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
22350a5e423SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
22450a5e423SFlorian Hahn
22550a5e423SFlorian Hahnexit:
22650a5e423SFlorian Hahn  ret i4 3
22750a5e423SFlorian Hahn}
22850a5e423SFlorian Hahn
22950a5e423SFlorian Hahndefine i4 @inc_ptr_src_uge_end_no_nsw_add_sge_0(ptr %src, ptr %lower, ptr %upper, i16 %idx, i16 %N, i16 %step) {
23050a5e423SFlorian Hahn; CHECK-LABEL: @inc_ptr_src_uge_end_no_nsw_add_sge_0(
23150a5e423SFlorian Hahn; CHECK-NEXT:  entry.1:
23250a5e423SFlorian Hahn; CHECK-NEXT:    [[IDX_POS:%.*]] = icmp sge i16 [[IDX:%.*]], 0
23350a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[IDX_POS]], label [[ENTRY:%.*]], label [[TRAP_BB:%.*]]
23450a5e423SFlorian Hahn; CHECK:       entry:
23550a5e423SFlorian Hahn; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[IDX]]
23650a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC_IDX]], [[LOWER:%.*]]
23750a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[CMP_SRC_START]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
23850a5e423SFlorian Hahn; CHECK:       trap.bb:
23950a5e423SFlorian Hahn; CHECK-NEXT:    ret i4 2
24050a5e423SFlorian Hahn; CHECK:       step.check:
24150a5e423SFlorian Hahn; CHECK-NEXT:    [[NEXT:%.*]] = add i16 [[IDX]], 2
24250a5e423SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[NEXT]]
24350a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
24450a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER:%.*]]
24550a5e423SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
24650a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT:%.*]]
24750a5e423SFlorian Hahn; CHECK:       exit:
24850a5e423SFlorian Hahn; CHECK-NEXT:    ret i4 3
24950a5e423SFlorian Hahn;
25050a5e423SFlorian Hahnentry.1:
25150a5e423SFlorian Hahn  %idx.pos = icmp sge i16 %idx, 0
25250a5e423SFlorian Hahn  br i1 %idx.pos, label %entry, label %trap.bb
25350a5e423SFlorian Hahn
25450a5e423SFlorian Hahnentry:
25550a5e423SFlorian Hahn  %src.idx = getelementptr inbounds i8, ptr %src, i16 %idx
25650a5e423SFlorian Hahn  %cmp.src.start = icmp ult ptr %src.idx, %lower
25750a5e423SFlorian Hahn  br i1 %cmp.src.start, label %trap.bb, label %step.check
25850a5e423SFlorian Hahn
25950a5e423SFlorian Hahntrap.bb:
26050a5e423SFlorian Hahn  ret i4 2
26150a5e423SFlorian Hahn
26250a5e423SFlorian Hahnstep.check:
26350a5e423SFlorian Hahn  %next = add i16 %idx, 2
26450a5e423SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 %next
26550a5e423SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
26650a5e423SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
26750a5e423SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
26850a5e423SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
26950a5e423SFlorian Hahn
27050a5e423SFlorian Hahnexit:
27150a5e423SFlorian Hahn  ret i4 3
27250a5e423SFlorian Hahn}
27350a5e423SFlorian Hahndefine i4 @ptr_N_step_zext_n_zext(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
27450a5e423SFlorian Hahn; CHECK-LABEL: @ptr_N_step_zext_n_zext(
27550a5e423SFlorian Hahn; CHECK-NEXT:  entry:
27650a5e423SFlorian Hahn; CHECK-NEXT:    [[N_ADD_1:%.*]] = add nuw nsw i16 [[N:%.*]], 1
27750a5e423SFlorian Hahn; CHECK-NEXT:    [[N_ADD_1_EXT:%.*]] = zext i16 [[N_ADD_1]] to i32
27850a5e423SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i32 [[N_ADD_1_EXT]]
27950a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
28050a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
28150a5e423SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
28250a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
28350a5e423SFlorian Hahn; CHECK:       trap.bb:
28450a5e423SFlorian Hahn; CHECK-NEXT:    ret i4 2
28550a5e423SFlorian Hahn; CHECK:       step.check:
28650a5e423SFlorian Hahn; CHECK-NEXT:    [[STEP_ADD_1:%.*]] = add nuw nsw i16 [[STEP:%.*]], 1
28750a5e423SFlorian Hahn; CHECK-NEXT:    [[STEP_ADD_1_EXT:%.*]] = zext i16 [[STEP_ADD_1]] to i32
28850a5e423SFlorian Hahn; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i32 [[STEP_ADD_1_EXT]], [[N_ADD_1_EXT]]
28950a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
29050a5e423SFlorian Hahn; CHECK:       ptr.check:
29150a5e423SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i32 [[STEP_ADD_1_EXT]]
292*fbcf8a8cSFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 false, false
29350a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
29450a5e423SFlorian Hahn; CHECK:       exit:
29550a5e423SFlorian Hahn; CHECK-NEXT:    ret i4 3
29650a5e423SFlorian Hahn;
29750a5e423SFlorian Hahnentry:
29850a5e423SFlorian Hahn  %N.add.1 = add nuw nsw i16 %N, 1
29950a5e423SFlorian Hahn  %N.add.1.ext = zext i16 %N.add.1 to i32
30050a5e423SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i32 %N.add.1.ext
30150a5e423SFlorian Hahn  %cmp.src.start = icmp ult ptr %src, %lower
30250a5e423SFlorian Hahn  %cmp.src.end = icmp uge ptr %src.end, %upper
30350a5e423SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
30450a5e423SFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
30550a5e423SFlorian Hahn
30650a5e423SFlorian Hahntrap.bb:
30750a5e423SFlorian Hahn  ret i4 2
30850a5e423SFlorian Hahn
30950a5e423SFlorian Hahnstep.check:
31050a5e423SFlorian Hahn  %step.add.1 = add nuw nsw i16 %step, 1
31150a5e423SFlorian Hahn  %step.add.1.ext = zext i16 %step.add.1 to i32
31250a5e423SFlorian Hahn  %step.ult.N = icmp ult i32 %step.add.1.ext, %N.add.1.ext
31350a5e423SFlorian Hahn  br i1 %step.ult.N, label %ptr.check, label %exit
31450a5e423SFlorian Hahn
31550a5e423SFlorian Hahnptr.check:
31650a5e423SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i32 %step.add.1.ext
31750a5e423SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
31850a5e423SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
31950a5e423SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
32050a5e423SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
32150a5e423SFlorian Hahn
32250a5e423SFlorian Hahnexit:
32350a5e423SFlorian Hahn  ret i4 3
32450a5e423SFlorian Hahn}
32550a5e423SFlorian Hahn
32650a5e423SFlorian Hahndefine i4 @ptr_N_step_zext_n_zext_out_of_bounds(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
32750a5e423SFlorian Hahn; CHECK-LABEL: @ptr_N_step_zext_n_zext_out_of_bounds(
32850a5e423SFlorian Hahn; CHECK-NEXT:  entry:
32950a5e423SFlorian Hahn; CHECK-NEXT:    [[N_ADD_2:%.*]] = add nuw nsw i16 [[N:%.*]], 2
33050a5e423SFlorian Hahn; CHECK-NEXT:    [[N_ADD_2_EXT:%.*]] = zext i16 [[N_ADD_2]] to i32
33150a5e423SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i32 [[N_ADD_2_EXT]]
33250a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
33350a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
33450a5e423SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
33550a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
33650a5e423SFlorian Hahn; CHECK:       trap.bb:
33750a5e423SFlorian Hahn; CHECK-NEXT:    ret i4 2
33850a5e423SFlorian Hahn; CHECK:       step.check:
33950a5e423SFlorian Hahn; CHECK-NEXT:    [[STEP_ADD_2:%.*]] = add nuw nsw i16 [[STEP:%.*]], 2
34050a5e423SFlorian Hahn; CHECK-NEXT:    [[STEP_ADD_2_EXT:%.*]] = zext i16 [[STEP_ADD_2]] to i32
34150a5e423SFlorian Hahn; CHECK-NEXT:    [[STEP_EXT:%.*]] = zext i16 [[STEP]] to i32
34250a5e423SFlorian Hahn; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i32 [[STEP_EXT]], [[N_ADD_2_EXT]]
34350a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
34450a5e423SFlorian Hahn; CHECK:       ptr.check:
34550a5e423SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i32 [[STEP_ADD_2_EXT]]
34650a5e423SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
347*fbcf8a8cSFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 false, [[CMP_STEP_END]]
34850a5e423SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
34950a5e423SFlorian Hahn; CHECK:       exit:
35050a5e423SFlorian Hahn; CHECK-NEXT:    ret i4 3
35150a5e423SFlorian Hahn;
35250a5e423SFlorian Hahnentry:
35350a5e423SFlorian Hahn  %N.add.2 = add nuw nsw i16 %N, 2
35450a5e423SFlorian Hahn  %N.add.2.ext = zext i16 %N.add.2 to i32
35550a5e423SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i32 %N.add.2.ext
35650a5e423SFlorian Hahn  %cmp.src.start = icmp ult ptr %src, %lower
35750a5e423SFlorian Hahn  %cmp.src.end = icmp uge ptr %src.end, %upper
35850a5e423SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
35950a5e423SFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
36050a5e423SFlorian Hahn
36150a5e423SFlorian Hahntrap.bb:
36250a5e423SFlorian Hahn  ret i4 2
36350a5e423SFlorian Hahn
36450a5e423SFlorian Hahnstep.check:
36550a5e423SFlorian Hahn  %step.add.2 = add nuw nsw i16 %step, 2
36650a5e423SFlorian Hahn  %step.add.2.ext = zext i16 %step.add.2 to i32
36750a5e423SFlorian Hahn  %step.ext = zext i16 %step to i32
36850a5e423SFlorian Hahn  %step.ult.N = icmp ult i32 %step.ext, %N.add.2.ext
36950a5e423SFlorian Hahn  br i1 %step.ult.N, label %ptr.check, label %exit
37050a5e423SFlorian Hahn
37150a5e423SFlorian Hahnptr.check:
37250a5e423SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i32 %step.add.2.ext
37350a5e423SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
37450a5e423SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
37550a5e423SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
37650a5e423SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
37750a5e423SFlorian Hahn
37850a5e423SFlorian Hahnexit:
37950a5e423SFlorian Hahn  ret i4 3
38050a5e423SFlorian Hahn}
381b0fb7161SFlorian Hahn
382b0fb7161SFlorian Hahndefine i1 @gep_count_add_1_sge_known_ult_1(i32 %count, ptr %p) {
383b0fb7161SFlorian Hahn; CHECK-LABEL: @gep_count_add_1_sge_known_ult_1(
384b0fb7161SFlorian Hahn; CHECK-NEXT:  entry:
385b0fb7161SFlorian Hahn; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
386b0fb7161SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
387b0fb7161SFlorian Hahn; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
388b0fb7161SFlorian Hahn; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
389b0fb7161SFlorian Hahn; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -1
390b0fb7161SFlorian Hahn; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
391b0fb7161SFlorian Hahn; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
392b0fb7161SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr [[GEP_SUB]], [[GEP_COUNT]]
393b0fb7161SFlorian Hahn; CHECK-NEXT:    ret i1 [[C]]
394b0fb7161SFlorian Hahn;
395b0fb7161SFlorian Hahnentry:
396b0fb7161SFlorian Hahn  %sge = icmp sge i32 %count, 1
397b0fb7161SFlorian Hahn  call void @llvm.assume(i1 %sge)
398b0fb7161SFlorian Hahn  %count.ext = zext i32 %count to i64
399b0fb7161SFlorian Hahn  %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
400b0fb7161SFlorian Hahn  %sub = add nsw i32 %count, -1
401b0fb7161SFlorian Hahn  %sub.ext = zext i32 %sub to i64
402b0fb7161SFlorian Hahn  %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
403b0fb7161SFlorian Hahn  %c = icmp ult ptr %gep.sub, %gep.count
404b0fb7161SFlorian Hahn  ;%2 = icmp uge ptr %0, %p
405b0fb7161SFlorian Hahn  ret i1 %c
406b0fb7161SFlorian Hahn}
407b0fb7161SFlorian Hahn
408b0fb7161SFlorian Hahndefine i1 @gep_count_add_1_sge_known_uge_1(i32 %count, ptr %p) {
409b0fb7161SFlorian Hahn; CHECK-LABEL: @gep_count_add_1_sge_known_uge_1(
410b0fb7161SFlorian Hahn; CHECK-NEXT:  entry:
411b0fb7161SFlorian Hahn; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
412b0fb7161SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
413b0fb7161SFlorian Hahn; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
414b0fb7161SFlorian Hahn; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
415b0fb7161SFlorian Hahn; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -1
416b0fb7161SFlorian Hahn; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
417b0fb7161SFlorian Hahn; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
418b0fb7161SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp uge ptr [[GEP_SUB]], [[P]]
419b0fb7161SFlorian Hahn; CHECK-NEXT:    ret i1 [[C]]
420b0fb7161SFlorian Hahn;
421b0fb7161SFlorian Hahnentry:
422b0fb7161SFlorian Hahn  %sge = icmp sge i32 %count, 1
423b0fb7161SFlorian Hahn  call void @llvm.assume(i1 %sge)
424b0fb7161SFlorian Hahn  %count.ext = zext i32 %count to i64
425b0fb7161SFlorian Hahn  %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
426b0fb7161SFlorian Hahn  %sub = add nsw i32 %count, -1
427b0fb7161SFlorian Hahn  %sub.ext = zext i32 %sub to i64
428b0fb7161SFlorian Hahn  %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
429b0fb7161SFlorian Hahn  %c = icmp uge ptr %gep.sub, %p
430b0fb7161SFlorian Hahn  ret i1 %c
431b0fb7161SFlorian Hahn}
432b0fb7161SFlorian Hahn
433b0fb7161SFlorian Hahndefine i1 @gep_count_add_2_sge_not_known_ult_1(i32 %count, ptr %p) {
434b0fb7161SFlorian Hahn; CHECK-LABEL: @gep_count_add_2_sge_not_known_ult_1(
435b0fb7161SFlorian Hahn; CHECK-NEXT:  entry:
436b0fb7161SFlorian Hahn; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
437b0fb7161SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
438b0fb7161SFlorian Hahn; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
439b0fb7161SFlorian Hahn; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
440b0fb7161SFlorian Hahn; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -2
441b0fb7161SFlorian Hahn; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
442b0fb7161SFlorian Hahn; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
443b0fb7161SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr [[GEP_SUB]], [[GEP_COUNT]]
444b0fb7161SFlorian Hahn; CHECK-NEXT:    ret i1 [[C]]
445b0fb7161SFlorian Hahn;
446b0fb7161SFlorian Hahnentry:
447b0fb7161SFlorian Hahn  %sge = icmp sge i32 %count, 1
448b0fb7161SFlorian Hahn  call void @llvm.assume(i1 %sge)
449b0fb7161SFlorian Hahn  %count.ext = zext i32 %count to i64
450b0fb7161SFlorian Hahn  %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
451b0fb7161SFlorian Hahn  %sub = add nsw i32 %count, -2
452b0fb7161SFlorian Hahn  %sub.ext = zext i32 %sub to i64
453b0fb7161SFlorian Hahn  %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
454b0fb7161SFlorian Hahn  %c = icmp ult ptr %gep.sub, %gep.count
455b0fb7161SFlorian Hahn  ret i1 %c
456b0fb7161SFlorian Hahn}
457b0fb7161SFlorian Hahn
458b0fb7161SFlorian Hahndefine i1 @gep_count_add_2_sge_not_known_uge_1(i32 %count, ptr %p) {
459b0fb7161SFlorian Hahn; CHECK-LABEL: @gep_count_add_2_sge_not_known_uge_1(
460b0fb7161SFlorian Hahn; CHECK-NEXT:  entry:
461b0fb7161SFlorian Hahn; CHECK-NEXT:    [[SGE:%.*]] = icmp sge i32 [[COUNT:%.*]], 1
462b0fb7161SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE]])
463b0fb7161SFlorian Hahn; CHECK-NEXT:    [[COUNT_EXT:%.*]] = zext i32 [[COUNT]] to i64
464b0fb7161SFlorian Hahn; CHECK-NEXT:    [[GEP_COUNT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[COUNT_EXT]]
465b0fb7161SFlorian Hahn; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[COUNT]], -2
466b0fb7161SFlorian Hahn; CHECK-NEXT:    [[SUB_EXT:%.*]] = zext i32 [[SUB]] to i64
467b0fb7161SFlorian Hahn; CHECK-NEXT:    [[GEP_SUB:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 [[SUB_EXT]]
468b0fb7161SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp uge ptr [[GEP_SUB]], [[P]]
469b0fb7161SFlorian Hahn; CHECK-NEXT:    ret i1 [[C]]
470b0fb7161SFlorian Hahn;
471b0fb7161SFlorian Hahnentry:
472b0fb7161SFlorian Hahn  %sge = icmp sge i32 %count, 1
473b0fb7161SFlorian Hahn  call void @llvm.assume(i1 %sge)
474b0fb7161SFlorian Hahn  %count.ext = zext i32 %count to i64
475b0fb7161SFlorian Hahn  %gep.count = getelementptr inbounds i32, ptr %p, i64 %count.ext
476b0fb7161SFlorian Hahn  %sub = add nsw i32 %count, -2
477b0fb7161SFlorian Hahn  %sub.ext = zext i32 %sub to i64
478b0fb7161SFlorian Hahn  %gep.sub = getelementptr inbounds i32, ptr %p, i64 %sub.ext
479b0fb7161SFlorian Hahn  %c = icmp uge ptr %gep.sub, %p
480b0fb7161SFlorian Hahn  ret i1 %c
481b0fb7161SFlorian Hahn}
482