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