114da287eSFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 28ebb3eacSBjorn Pettersson; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 314da287eSFlorian Hahn 4c5e1ddb6SFlorian Hahndeclare void @llvm.assume(i1 noundef) #0 514da287eSFlorian Hahn 6c5e1ddb6SFlorian Hahndefine i1 @gep_constant_positive_index(ptr %dst, ptr %lower, ptr %upper) { 7a405ecffSFlorian Hahn; CHECK-LABEL: @gep_constant_positive_index( 8c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 4 9c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[PRE_DST_LOWER:%.*]] = icmp uge ptr [[DST]], [[LOWER:%.*]] 10c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[PRE_DST_UPPER:%.*]] = icmp ult ptr [[DST_ADD_4]], [[UPPER:%.*]] 11a405ecffSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[PRE_DST_LOWER]], [[PRE_DST_UPPER]] 12a405ecffSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]] 13a405ecffSFlorian Hahn; CHECK: then: 14a405ecffSFlorian Hahn; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true 15c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3 16a405ecffSFlorian Hahn; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], true 17a405ecffSFlorian Hahn; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[RES_2]], true 18a405ecffSFlorian Hahn; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], true 19a405ecffSFlorian Hahn; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true 20c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[DST_ADD_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5 21c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_DST_ADD_5_UPPER:%.*]] = icmp ult ptr [[DST_ADD_5]], [[UPPER]] 22a405ecffSFlorian Hahn; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], true 23a405ecffSFlorian Hahn; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[CMP_DST_ADD_5_UPPER]] 24a405ecffSFlorian Hahn; CHECK-NEXT: ret i1 [[RES_7]] 25a405ecffSFlorian Hahn; CHECK: else: 26a405ecffSFlorian Hahn; CHECK-NEXT: ret i1 false 27a405ecffSFlorian Hahn; 28c5e1ddb6SFlorian Hahn %dst.add.4 = getelementptr inbounds i8, ptr %dst, i64 4 29c5e1ddb6SFlorian Hahn %pre.dst.lower = icmp uge ptr %dst, %lower 30c5e1ddb6SFlorian Hahn %pre.dst.upper = icmp ult ptr %dst.add.4, %upper 31a405ecffSFlorian Hahn %and = and i1 %pre.dst.lower, %pre.dst.upper 32a405ecffSFlorian Hahn br i1 %and, label %then, label %else 33a405ecffSFlorian Hahn 34a405ecffSFlorian Hahnthen: 35c5e1ddb6SFlorian Hahn %cmp.dst.lower = icmp uge ptr %dst, %lower 36c5e1ddb6SFlorian Hahn %cmp.dst.upper = icmp ult ptr %dst, %upper 37a405ecffSFlorian Hahn %res.1 = xor i1 %cmp.dst.lower, %cmp.dst.upper 38c5e1ddb6SFlorian Hahn %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3 39c5e1ddb6SFlorian Hahn %cmp.dst.add.3.lower = icmp uge ptr %dst.add.3, %lower 40c5e1ddb6SFlorian Hahn %cmp.dst.add.3.upper = icmp ult ptr %dst.add.3, %upper 41a405ecffSFlorian Hahn %res.2 = xor i1 %res.1, %cmp.dst.add.3.lower 42a405ecffSFlorian Hahn %res.3 = xor i1 %res.2, %cmp.dst.add.3.upper 43c5e1ddb6SFlorian Hahn %cmp.dst.add.4.lower = icmp uge ptr %dst.add.4, %lower 44c5e1ddb6SFlorian Hahn %cmp.dst.add.4.upper = icmp ult ptr %dst.add.4, %upper 45a405ecffSFlorian Hahn %res.4 = xor i1 %res.3, %cmp.dst.add.4.lower 46a405ecffSFlorian Hahn %res.5 = xor i1 %res.4, %cmp.dst.add.4.upper 47c5e1ddb6SFlorian Hahn %dst.add.5 = getelementptr inbounds i8, ptr %dst, i64 5 48c5e1ddb6SFlorian Hahn %cmp.dst.add.5.lower = icmp uge ptr %dst.add.5, %lower 49c5e1ddb6SFlorian Hahn %cmp.dst.add.5.upper = icmp ult ptr %dst.add.5, %upper 50a405ecffSFlorian Hahn %res.6 = xor i1 %res.5, %cmp.dst.add.5.lower 51a405ecffSFlorian Hahn %res.7 = xor i1 %res.6, %cmp.dst.add.5.upper 52a405ecffSFlorian Hahn ret i1 %res.7 53a405ecffSFlorian Hahn 54a405ecffSFlorian Hahnelse: 55a405ecffSFlorian Hahn ret i1 false 56a405ecffSFlorian Hahn} 57a405ecffSFlorian Hahn 58c5e1ddb6SFlorian Hahndefine i1 @gep_constant_negative_index(ptr %dst, ptr %lower, ptr %upper) { 59a405ecffSFlorian Hahn; CHECK-LABEL: @gep_constant_negative_index( 60c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[DST_SUB_4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 -4 61c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[PRE_DST_LOWER:%.*]] = icmp uge ptr [[DST]], [[LOWER:%.*]] 62c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[PRE_DST_UPPER:%.*]] = icmp ult ptr [[DST_SUB_4]], [[UPPER:%.*]] 63a405ecffSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[PRE_DST_LOWER]], [[PRE_DST_UPPER]] 64a405ecffSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]] 65a405ecffSFlorian Hahn; CHECK: then: 66c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_DST_UPPER:%.*]] = icmp ult ptr [[DST]], [[UPPER]] 67a405ecffSFlorian Hahn; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[CMP_DST_UPPER]] 68c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -3 69c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_DST_SUB_3_LOWER:%.*]] = icmp uge ptr [[DST_SUB_3]], [[LOWER]] 70c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_DST_SUB_3_UPPER:%.*]] = icmp ult ptr [[DST_SUB_3]], [[UPPER]] 71a405ecffSFlorian Hahn; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_DST_SUB_3_LOWER]] 72a405ecffSFlorian Hahn; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[RES_2]], [[CMP_DST_SUB_3_UPPER]] 73c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_DST_SUB_4_LOWER:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]] 74a405ecffSFlorian Hahn; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[CMP_DST_SUB_4_LOWER]] 756a834d2fSFlorian Hahn; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true 76c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[DST_SUB_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -5 77c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_DST_SUB_5_LOWER:%.*]] = icmp uge ptr [[DST_SUB_5]], [[LOWER]] 78a405ecffSFlorian Hahn; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[CMP_DST_SUB_5_LOWER]] 796a834d2fSFlorian Hahn; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], true 80a405ecffSFlorian Hahn; CHECK-NEXT: ret i1 [[RES_7]] 81a405ecffSFlorian Hahn; CHECK: else: 82c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ELSE_CMP_DST_LOWER:%.*]] = icmp uge ptr [[DST]], [[LOWER]] 83c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ELSE_CMP_DST_UPPER:%.*]] = icmp ult ptr [[DST]], [[UPPER]] 84a405ecffSFlorian Hahn; CHECK-NEXT: [[ELSE_RES_1:%.*]] = xor i1 [[ELSE_CMP_DST_LOWER]], [[ELSE_CMP_DST_UPPER]] 85c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ELSE_DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -3 86c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ELSE_CMP_DST_SUB_3_LOWER:%.*]] = icmp uge ptr [[ELSE_DST_SUB_3]], [[LOWER]] 87c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ELSE_CMP_DST_SUB_3_UPPER:%.*]] = icmp ult ptr [[ELSE_DST_SUB_3]], [[UPPER]] 88a405ecffSFlorian Hahn; CHECK-NEXT: [[ELSE_RES_2:%.*]] = xor i1 [[ELSE_RES_1]], [[ELSE_CMP_DST_SUB_3_LOWER]] 89a405ecffSFlorian Hahn; CHECK-NEXT: [[ELSE_RES_3:%.*]] = xor i1 [[ELSE_RES_2]], [[ELSE_CMP_DST_SUB_3_UPPER]] 90c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ELSE_CMP_DST_SUB_4_LOWER:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]] 91c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ELSE_CMP_DST_SUB_4_UPPER:%.*]] = icmp ult ptr [[DST_SUB_4]], [[UPPER]] 92a405ecffSFlorian Hahn; CHECK-NEXT: [[ELSE_RES_4:%.*]] = xor i1 [[ELSE_RES_3]], [[ELSE_CMP_DST_SUB_4_LOWER]] 93a405ecffSFlorian Hahn; CHECK-NEXT: [[ELSE_RES_5:%.*]] = xor i1 [[ELSE_RES_4]], [[ELSE_CMP_DST_SUB_4_UPPER]] 94c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ELSE_DST_SUB_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -5 95c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ELSE_CMP_DST_SUB_5_LOWER:%.*]] = icmp uge ptr [[ELSE_DST_SUB_5]], [[LOWER]] 96c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[ELSE_CMP_DST_SUB_5_UPPER:%.*]] = icmp ult ptr [[ELSE_DST_SUB_5]], [[UPPER]] 97a405ecffSFlorian Hahn; CHECK-NEXT: [[ELSE_RES_6:%.*]] = xor i1 [[ELSE_RES_5]], [[ELSE_CMP_DST_SUB_5_LOWER]] 98a405ecffSFlorian Hahn; CHECK-NEXT: [[ELSE_RES_7:%.*]] = xor i1 [[ELSE_RES_6]], [[ELSE_CMP_DST_SUB_5_UPPER]] 99a405ecffSFlorian Hahn; CHECK-NEXT: ret i1 [[ELSE_RES_7]] 100a405ecffSFlorian Hahn; 101c5e1ddb6SFlorian Hahn %dst.sub.4 = getelementptr inbounds i8, ptr %dst, i64 -4 102c5e1ddb6SFlorian Hahn %pre.dst.lower = icmp uge ptr %dst, %lower 103c5e1ddb6SFlorian Hahn %pre.dst.upper = icmp ult ptr %dst.sub.4, %upper 104a405ecffSFlorian Hahn %and = and i1 %pre.dst.lower, %pre.dst.upper 105a405ecffSFlorian Hahn br i1 %and, label %then, label %else 106a405ecffSFlorian Hahn 107a405ecffSFlorian Hahnthen: 108c5e1ddb6SFlorian Hahn %cmp.dst.lower = icmp uge ptr %dst, %lower 109c5e1ddb6SFlorian Hahn %cmp.dst.upper = icmp ult ptr %dst, %upper 110a405ecffSFlorian Hahn %res.1 = xor i1 %cmp.dst.lower, %cmp.dst.upper 111c5e1ddb6SFlorian Hahn %dst.sub.3 = getelementptr inbounds i8, ptr %dst, i64 -3 112c5e1ddb6SFlorian Hahn %cmp.dst.sub.3.lower = icmp uge ptr %dst.sub.3, %lower 113c5e1ddb6SFlorian Hahn %cmp.dst.sub.3.upper = icmp ult ptr %dst.sub.3, %upper 114a405ecffSFlorian Hahn %res.2 = xor i1 %res.1, %cmp.dst.sub.3.lower 115a405ecffSFlorian Hahn %res.3 = xor i1 %res.2, %cmp.dst.sub.3.upper 116c5e1ddb6SFlorian Hahn %cmp.dst.sub.4.lower = icmp uge ptr %dst.sub.4, %lower 117c5e1ddb6SFlorian Hahn %cmp.dst.sub.4.upper = icmp ult ptr %dst.sub.4, %upper 118a405ecffSFlorian Hahn %res.4 = xor i1 %res.3, %cmp.dst.sub.4.lower 119a405ecffSFlorian Hahn %res.5 = xor i1 %res.4, %cmp.dst.sub.4.upper 120c5e1ddb6SFlorian Hahn %dst.sub.5 = getelementptr inbounds i8, ptr %dst, i64 -5 121c5e1ddb6SFlorian Hahn %cmp.dst.sub.5.lower = icmp uge ptr %dst.sub.5, %lower 122c5e1ddb6SFlorian Hahn %cmp.dst.sub.5.upper = icmp ult ptr %dst.sub.5, %upper 123a405ecffSFlorian Hahn %res.6 = xor i1 %res.5, %cmp.dst.sub.5.lower 124a405ecffSFlorian Hahn %res.7 = xor i1 %res.6, %cmp.dst.sub.5.upper 125a405ecffSFlorian Hahn ret i1 %res.7 126a405ecffSFlorian Hahn 127a405ecffSFlorian Hahnelse: 128c5e1ddb6SFlorian Hahn %else.cmp.dst.lower = icmp uge ptr %dst, %lower 129c5e1ddb6SFlorian Hahn %else.cmp.dst.upper = icmp ult ptr %dst, %upper 130a405ecffSFlorian Hahn %else.res.1 = xor i1 %else.cmp.dst.lower, %else.cmp.dst.upper 131c5e1ddb6SFlorian Hahn %else.dst.sub.3 = getelementptr inbounds i8, ptr %dst, i64 -3 132c5e1ddb6SFlorian Hahn %else.cmp.dst.sub.3.lower = icmp uge ptr %else.dst.sub.3, %lower 133c5e1ddb6SFlorian Hahn %else.cmp.dst.sub.3.upper = icmp ult ptr %else.dst.sub.3, %upper 134a405ecffSFlorian Hahn %else.res.2 = xor i1 %else.res.1, %else.cmp.dst.sub.3.lower 135a405ecffSFlorian Hahn %else.res.3 = xor i1 %else.res.2, %else.cmp.dst.sub.3.upper 136c5e1ddb6SFlorian Hahn %else.cmp.dst.sub.4.lower = icmp uge ptr %dst.sub.4, %lower 137c5e1ddb6SFlorian Hahn %else.cmp.dst.sub.4.upper = icmp ult ptr %dst.sub.4, %upper 138a405ecffSFlorian Hahn %else.res.4 = xor i1 %else.res.3, %else.cmp.dst.sub.4.lower 139a405ecffSFlorian Hahn %else.res.5 = xor i1 %else.res.4, %else.cmp.dst.sub.4.upper 140c5e1ddb6SFlorian Hahn %else.dst.sub.5 = getelementptr inbounds i8, ptr %dst, i64 -5 141c5e1ddb6SFlorian Hahn %else.cmp.dst.sub.5.lower = icmp uge ptr %else.dst.sub.5, %lower 142c5e1ddb6SFlorian Hahn %else.cmp.dst.sub.5.upper = icmp ult ptr %else.dst.sub.5, %upper 143a405ecffSFlorian Hahn %else.res.6 = xor i1 %else.res.5, %else.cmp.dst.sub.5.lower 144a405ecffSFlorian Hahn %else.res.7 = xor i1 %else.res.6, %else.cmp.dst.sub.5.upper 145a405ecffSFlorian Hahn ret i1 %else.res.7 146a405ecffSFlorian Hahn} 147a405ecffSFlorian Hahn 148c5e1ddb6SFlorian Hahndefine i4 @ptr_N_signed_positive_explicit_check_constant_step(ptr %src, ptr %lower, ptr %upper, i16 %N) { 14914da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step( 15014da287eSFlorian Hahn; CHECK-NEXT: entry: 15114da287eSFlorian Hahn; CHECK-NEXT: [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0 15214da287eSFlorian Hahn; CHECK-NEXT: br i1 [[N_POS]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]] 15314da287eSFlorian Hahn; CHECK: entry.1: 154c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N]] 155c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]] 156c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]] 15714da287eSFlorian Hahn; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]] 15814da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]] 15914da287eSFlorian Hahn; CHECK: trap.bb: 16014da287eSFlorian Hahn; CHECK-NEXT: ret i4 2 16114da287eSFlorian Hahn; CHECK: step.check: 16214da287eSFlorian Hahn; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 1, [[N]] 16314da287eSFlorian Hahn; CHECK-NEXT: br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]] 16414da287eSFlorian Hahn; CHECK: ptr.check: 165c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1 1660a781d98SFlorian Hahn; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, false 16714da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]] 16814da287eSFlorian Hahn; CHECK: exit: 16914da287eSFlorian Hahn; CHECK-NEXT: ret i4 3 17014da287eSFlorian Hahn; 17114da287eSFlorian Hahnentry: 17214da287eSFlorian Hahn %N.pos = icmp sge i16 %N, 0 17314da287eSFlorian Hahn br i1 %N.pos, label %entry.1, label %trap.bb 17414da287eSFlorian Hahn 17514da287eSFlorian Hahnentry.1: 176c5e1ddb6SFlorian Hahn %src.end = getelementptr inbounds i8, ptr %src, i16 %N 177c5e1ddb6SFlorian Hahn %cmp.src.start = icmp ult ptr %src, %lower 178c5e1ddb6SFlorian Hahn %cmp.src.end = icmp uge ptr %src.end, %upper 17914da287eSFlorian Hahn %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end 18014da287eSFlorian Hahn br i1 %or.precond.0, label %trap.bb, label %step.check 18114da287eSFlorian Hahn 18214da287eSFlorian Hahntrap.bb: 18314da287eSFlorian Hahn ret i4 2 18414da287eSFlorian Hahn 18514da287eSFlorian Hahnstep.check: 18614da287eSFlorian Hahn %step.ult.N = icmp ult i16 1, %N 18714da287eSFlorian Hahn br i1 %step.ult.N, label %ptr.check, label %exit 18814da287eSFlorian Hahn 18914da287eSFlorian Hahnptr.check: 190c5e1ddb6SFlorian Hahn %src.step = getelementptr inbounds i8, ptr %src, i16 1 191c5e1ddb6SFlorian Hahn %cmp.step.start = icmp ult ptr %src.step, %lower 192c5e1ddb6SFlorian Hahn %cmp.step.end = icmp uge ptr %src.step, %upper 19314da287eSFlorian Hahn %or.check = or i1 %cmp.step.start, %cmp.step.end 19414da287eSFlorian Hahn br i1 %or.check, label %trap.bb, label %exit 19514da287eSFlorian Hahn 19614da287eSFlorian Hahnexit: 19714da287eSFlorian Hahn ret i4 3 19814da287eSFlorian Hahn} 19914da287eSFlorian Hahn 20014da287eSFlorian Hahn; Same as ptr_N_signed_positive_explicit_check_constant_step, but without inbounds. 201c5e1ddb6SFlorian Hahndefine i4 @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(ptr %src, ptr %lower, ptr %upper, i16 %N) { 20214da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds( 20314da287eSFlorian Hahn; CHECK-NEXT: entry: 20414da287eSFlorian Hahn; CHECK-NEXT: [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0 20514da287eSFlorian Hahn; CHECK-NEXT: br i1 [[N_POS]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]] 20614da287eSFlorian Hahn; CHECK: entry.1: 207c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr i8, ptr [[SRC:%.*]], i16 [[N]] 208c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]] 209c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]] 21014da287eSFlorian Hahn; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]] 21114da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]] 21214da287eSFlorian Hahn; CHECK: trap.bb: 21314da287eSFlorian Hahn; CHECK-NEXT: ret i4 2 21414da287eSFlorian Hahn; CHECK: step.check: 21514da287eSFlorian Hahn; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 1, [[N]] 21614da287eSFlorian Hahn; CHECK-NEXT: br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]] 21714da287eSFlorian Hahn; CHECK: ptr.check: 218c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr i8, ptr [[SRC]], i16 1 219c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]] 220c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]] 221853c52c9SFlorian Hahn; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]] 22214da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]] 22314da287eSFlorian Hahn; CHECK: exit: 22414da287eSFlorian Hahn; CHECK-NEXT: ret i4 3 22514da287eSFlorian Hahn; 22614da287eSFlorian Hahnentry: 22714da287eSFlorian Hahn %N.pos = icmp sge i16 %N, 0 22814da287eSFlorian Hahn br i1 %N.pos, label %entry.1, label %trap.bb 22914da287eSFlorian Hahn 23014da287eSFlorian Hahnentry.1: 231c5e1ddb6SFlorian Hahn %src.end = getelementptr i8, ptr %src, i16 %N 232c5e1ddb6SFlorian Hahn %cmp.src.start = icmp ult ptr %src, %lower 233c5e1ddb6SFlorian Hahn %cmp.src.end = icmp uge ptr %src.end, %upper 23414da287eSFlorian Hahn %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end 23514da287eSFlorian Hahn br i1 %or.precond.0, label %trap.bb, label %step.check 23614da287eSFlorian Hahn 23714da287eSFlorian Hahntrap.bb: 23814da287eSFlorian Hahn ret i4 2 23914da287eSFlorian Hahn 24014da287eSFlorian Hahnstep.check: 24114da287eSFlorian Hahn %step.ult.N = icmp ult i16 1, %N 24214da287eSFlorian Hahn br i1 %step.ult.N, label %ptr.check, label %exit 24314da287eSFlorian Hahn 24414da287eSFlorian Hahnptr.check: 245c5e1ddb6SFlorian Hahn %src.step = getelementptr i8, ptr %src, i16 1 246c5e1ddb6SFlorian Hahn %cmp.step.start = icmp ult ptr %src.step, %lower 247c5e1ddb6SFlorian Hahn %cmp.step.end = icmp uge ptr %src.step, %upper 24814da287eSFlorian Hahn %or.check = or i1 %cmp.step.start, %cmp.step.end 24914da287eSFlorian Hahn br i1 %or.check, label %trap.bb, label %exit 25014da287eSFlorian Hahn 25114da287eSFlorian Hahnexit: 25214da287eSFlorian Hahn ret i4 3 25314da287eSFlorian Hahn} 25414da287eSFlorian Hahn 255c5e1ddb6SFlorian Hahndefine i4 @ptr_N_and_step_signed_positive_explicit_check_constant_step(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) { 25614da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_and_step_signed_positive_explicit_check_constant_step( 25714da287eSFlorian Hahn; CHECK-NEXT: entry: 25814da287eSFlorian Hahn; CHECK-NEXT: [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0 25914da287eSFlorian Hahn; CHECK-NEXT: [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0 26014da287eSFlorian Hahn; CHECK-NEXT: [[AND_1:%.*]] = and i1 [[N_POS]], [[STEP_POS]] 26114da287eSFlorian Hahn; CHECK-NEXT: br i1 [[AND_1]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]] 26214da287eSFlorian Hahn; CHECK: entry.1: 263c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N]] 264c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]] 265c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]] 26614da287eSFlorian Hahn; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]] 26714da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]] 26814da287eSFlorian Hahn; CHECK: trap.bb: 26914da287eSFlorian Hahn; CHECK-NEXT: ret i4 2 27014da287eSFlorian Hahn; CHECK: step.check: 27114da287eSFlorian Hahn; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP]], [[N]] 272098b0b18SFlorian Hahn; CHECK-NEXT: [[AND_2:%.*]] = and i1 true, [[STEP_ULT_N]] 27314da287eSFlorian Hahn; CHECK-NEXT: br i1 [[AND_2]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]] 27414da287eSFlorian Hahn; CHECK: ptr.check: 275c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1 2760a781d98SFlorian Hahn; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, false 27714da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]] 27814da287eSFlorian Hahn; CHECK: exit: 27914da287eSFlorian Hahn; CHECK-NEXT: ret i4 3 28014da287eSFlorian Hahn; 28114da287eSFlorian Hahnentry: 28214da287eSFlorian Hahn %N.pos = icmp sge i16 %N, 0 28314da287eSFlorian Hahn %step.pos = icmp sge i16 %step, 0 28414da287eSFlorian Hahn %and.1 = and i1 %N.pos, %step.pos 28514da287eSFlorian Hahn br i1 %and.1, label %entry.1, label %trap.bb 28614da287eSFlorian Hahn 28714da287eSFlorian Hahnentry.1: 288c5e1ddb6SFlorian Hahn %src.end = getelementptr inbounds i8, ptr %src, i16 %N 289c5e1ddb6SFlorian Hahn %cmp.src.start = icmp ult ptr %src, %lower 290c5e1ddb6SFlorian Hahn %cmp.src.end = icmp uge ptr %src.end, %upper 29114da287eSFlorian Hahn %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end 29214da287eSFlorian Hahn br i1 %or.precond.0, label %trap.bb, label %step.check 29314da287eSFlorian Hahn 29414da287eSFlorian Hahntrap.bb: 29514da287eSFlorian Hahn ret i4 2 29614da287eSFlorian Hahn 29714da287eSFlorian Hahnstep.check: 29814da287eSFlorian Hahn %step.uge.0 = icmp uge i16 %step, 0 29914da287eSFlorian Hahn %step.ult.N = icmp ult i16 %step, %N 30014da287eSFlorian Hahn %and.2 = and i1 %step.uge.0, %step.ult.N 30114da287eSFlorian Hahn br i1 %and.2, label %ptr.check, label %exit 30214da287eSFlorian Hahn 30314da287eSFlorian Hahnptr.check: 304c5e1ddb6SFlorian Hahn %src.step = getelementptr inbounds i8, ptr %src, i16 1 305c5e1ddb6SFlorian Hahn %cmp.step.start = icmp ult ptr %src.step, %lower 306c5e1ddb6SFlorian Hahn %cmp.step.end = icmp uge ptr %src.step, %upper 30714da287eSFlorian Hahn %or.check = or i1 %cmp.step.start, %cmp.step.end 30814da287eSFlorian Hahn br i1 %or.check, label %trap.bb, label %exit 30914da287eSFlorian Hahn 31014da287eSFlorian Hahnexit: 31114da287eSFlorian Hahn ret i4 3 31214da287eSFlorian Hahn} 31314da287eSFlorian Hahn 314c5e1ddb6SFlorian Hahndefine i4 @ptr_N_and_step_signed_positive_unsigned_checks_only(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) { 31514da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_and_step_signed_positive_unsigned_checks_only( 31614da287eSFlorian Hahn; CHECK-NEXT: entry: 317c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]] 318c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[NO_OVERFLOW:%.*]] = icmp ule ptr [[SRC]], [[SRC_END]] 31914da287eSFlorian Hahn; CHECK-NEXT: br i1 [[NO_OVERFLOW]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]] 32014da287eSFlorian Hahn; CHECK: entry.1: 321c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]] 322c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]] 32314da287eSFlorian Hahn; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]] 32414da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]] 32514da287eSFlorian Hahn; CHECK: trap.bb: 32614da287eSFlorian Hahn; CHECK-NEXT: ret i4 2 32714da287eSFlorian Hahn; CHECK: step.check: 32898e016d9SFlorian Hahn; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP:%.*]], [[N]] 32998e016d9SFlorian Hahn; CHECK-NEXT: [[AND_2:%.*]] = and i1 true, [[STEP_ULT_N]] 33014da287eSFlorian Hahn; CHECK-NEXT: br i1 [[AND_2]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]] 33114da287eSFlorian Hahn; CHECK: ptr.check: 332c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1 333c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]] 33406f3ef66SFlorian Hahn; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, [[CMP_STEP_END]] 33514da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]] 33614da287eSFlorian Hahn; CHECK: exit: 33714da287eSFlorian Hahn; CHECK-NEXT: ret i4 3 33814da287eSFlorian Hahn; 33914da287eSFlorian Hahnentry: 340c5e1ddb6SFlorian Hahn %src.end = getelementptr inbounds i8, ptr %src, i16 %N 341c5e1ddb6SFlorian Hahn %no.overflow = icmp ule ptr %src, %src.end 34214da287eSFlorian Hahn br i1 %no.overflow, label %entry.1, label %trap.bb 34314da287eSFlorian Hahn 34414da287eSFlorian Hahnentry.1: 345c5e1ddb6SFlorian Hahn %cmp.src.start = icmp ult ptr %src, %lower 346c5e1ddb6SFlorian Hahn %cmp.src.end = icmp uge ptr %src.end, %upper 34714da287eSFlorian Hahn %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end 34814da287eSFlorian Hahn br i1 %or.precond.0, label %trap.bb, label %step.check 34914da287eSFlorian Hahn 35014da287eSFlorian Hahntrap.bb: 35114da287eSFlorian Hahn ret i4 2 35214da287eSFlorian Hahn 35314da287eSFlorian Hahnstep.check: 35414da287eSFlorian Hahn %step.uge.0 = icmp uge i16 %step, 0 35514da287eSFlorian Hahn %step.ult.N = icmp ult i16 %step, %N 35614da287eSFlorian Hahn %and.2 = and i1 %step.uge.0, %step.ult.N 35714da287eSFlorian Hahn br i1 %and.2, label %ptr.check, label %exit 35814da287eSFlorian Hahn 35914da287eSFlorian Hahnptr.check: 360c5e1ddb6SFlorian Hahn %src.step = getelementptr inbounds i8, ptr %src, i16 1 361c5e1ddb6SFlorian Hahn %cmp.step.start = icmp ult ptr %src.step, %lower 362c5e1ddb6SFlorian Hahn %cmp.step.end = icmp uge ptr %src.step, %upper 36314da287eSFlorian Hahn %or.check = or i1 %cmp.step.start, %cmp.step.end 36414da287eSFlorian Hahn br i1 %or.check, label %trap.bb, label %exit 36514da287eSFlorian Hahn 36614da287eSFlorian Hahnexit: 36714da287eSFlorian Hahn ret i4 3 36814da287eSFlorian Hahn} 36914da287eSFlorian Hahn 370c5e1ddb6SFlorian Hahndefine i4 @ptr_N_signed_positive(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) { 37114da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_signed_positive( 37214da287eSFlorian Hahn; CHECK-NEXT: entry: 373c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]] 374c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]] 375c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]] 37614da287eSFlorian Hahn; CHECK-NEXT: [[N_NEG:%.*]] = icmp slt i16 [[N]], 0 37714da287eSFlorian Hahn; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]] 37814da287eSFlorian Hahn; CHECK-NEXT: [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[N_NEG]] 37914da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]] 38014da287eSFlorian Hahn; CHECK: trap.bb: 38114da287eSFlorian Hahn; CHECK-NEXT: ret i4 2 38214da287eSFlorian Hahn; CHECK: step.check: 38398e016d9SFlorian Hahn; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP:%.*]], [[N]] 38498e016d9SFlorian Hahn; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]] 38514da287eSFlorian Hahn; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]] 38614da287eSFlorian Hahn; CHECK: ptr.check: 387c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]] 388349375d0SFlorian Hahn; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 false, false 38914da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]] 39014da287eSFlorian Hahn; CHECK: exit: 39114da287eSFlorian Hahn; CHECK-NEXT: ret i4 3 39214da287eSFlorian Hahn; 39314da287eSFlorian Hahnentry: 394c5e1ddb6SFlorian Hahn %src.end = getelementptr inbounds i8, ptr %src, i16 %N 395c5e1ddb6SFlorian Hahn %cmp.src.start = icmp ult ptr %src, %lower 396c5e1ddb6SFlorian Hahn %cmp.src.end = icmp uge ptr %src.end, %upper 39714da287eSFlorian Hahn %N.neg = icmp slt i16 %N, 0 39814da287eSFlorian Hahn %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end 39914da287eSFlorian Hahn %or.precond.1 = or i1 %or.precond.0, %N.neg 40014da287eSFlorian Hahn br i1 %or.precond.1, label %trap.bb, label %step.check 40114da287eSFlorian Hahn 40214da287eSFlorian Hahntrap.bb: 40314da287eSFlorian Hahn ret i4 2 40414da287eSFlorian Hahn 40514da287eSFlorian Hahnstep.check: 40614da287eSFlorian Hahn %step.pos = icmp uge i16 %step, 0 40714da287eSFlorian Hahn %step.ult.N = icmp ult i16 %step, %N 40814da287eSFlorian Hahn %and.step = and i1 %step.pos, %step.ult.N 40914da287eSFlorian Hahn br i1 %and.step, label %ptr.check, label %exit 41014da287eSFlorian Hahn 41114da287eSFlorian Hahnptr.check: 412c5e1ddb6SFlorian Hahn %src.step = getelementptr inbounds i8, ptr %src, i16 %step 413c5e1ddb6SFlorian Hahn %cmp.step.start = icmp ult ptr %src.step, %lower 414c5e1ddb6SFlorian Hahn %cmp.step.end = icmp uge ptr %src.step, %upper 41514da287eSFlorian Hahn %or.check = or i1 %cmp.step.start, %cmp.step.end 41614da287eSFlorian Hahn br i1 %or.check, label %trap.bb, label %exit 41714da287eSFlorian Hahn 41814da287eSFlorian Hahnexit: 41914da287eSFlorian Hahn ret i4 3 42014da287eSFlorian Hahn} 42114da287eSFlorian Hahn 422c5e1ddb6SFlorian Hahndefine i4 @ptr_N_could_be_negative(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) { 42314da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_could_be_negative( 42414da287eSFlorian Hahn; CHECK-NEXT: entry: 425c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]] 426c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]] 427c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]] 42814da287eSFlorian Hahn; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]] 42914da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]] 43014da287eSFlorian Hahn; CHECK: trap.bb: 43114da287eSFlorian Hahn; CHECK-NEXT: ret i4 2 43214da287eSFlorian Hahn; CHECK: step.check: 43398e016d9SFlorian Hahn; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i8 [[STEP:%.*]], [[N]] 43498e016d9SFlorian Hahn; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]] 43514da287eSFlorian Hahn; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]] 43614da287eSFlorian Hahn; CHECK: ptr.check: 437c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]] 438c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]] 439c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]] 44006f3ef66SFlorian Hahn; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]] 44114da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]] 44214da287eSFlorian Hahn; CHECK: exit: 44314da287eSFlorian Hahn; CHECK-NEXT: ret i4 3 44414da287eSFlorian Hahn; 44514da287eSFlorian Hahnentry: 446c5e1ddb6SFlorian Hahn %src.end = getelementptr inbounds i8, ptr %src, i8 %N 447c5e1ddb6SFlorian Hahn %cmp.src.start = icmp ult ptr %src, %lower 448c5e1ddb6SFlorian Hahn %cmp.src.end = icmp uge ptr %src.end, %upper 44914da287eSFlorian Hahn %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end 45014da287eSFlorian Hahn br i1 %or.precond.0, label %trap.bb, label %step.check 45114da287eSFlorian Hahn 45214da287eSFlorian Hahntrap.bb: 45314da287eSFlorian Hahn ret i4 2 45414da287eSFlorian Hahn 45514da287eSFlorian Hahnstep.check: 4560bcfd4cbSFlorian Hahn %step.pos = icmp uge i8 %step, 0 4570bcfd4cbSFlorian Hahn %step.ult.N = icmp ult i8 %step, %N 45814da287eSFlorian Hahn %and.step = and i1 %step.pos, %step.ult.N 45914da287eSFlorian Hahn br i1 %and.step, label %ptr.check, label %exit 46014da287eSFlorian Hahn 46114da287eSFlorian Hahnptr.check: 462c5e1ddb6SFlorian Hahn %src.step = getelementptr inbounds i8, ptr %src, i8 %step 463c5e1ddb6SFlorian Hahn %cmp.step.start = icmp ult ptr %src.step, %lower 464c5e1ddb6SFlorian Hahn %cmp.step.end = icmp uge ptr %src.step, %upper 46514da287eSFlorian Hahn %or.check = or i1 %cmp.step.start, %cmp.step.end 46614da287eSFlorian Hahn br i1 %or.check, label %trap.bb, label %exit 46714da287eSFlorian Hahn 46814da287eSFlorian Hahnexit: 46914da287eSFlorian Hahn ret i4 3 47014da287eSFlorian Hahn} 47114da287eSFlorian Hahn 472c5e1ddb6SFlorian Hahndefine i4 @ptr_src_uge_end(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) { 47314da287eSFlorian Hahn; CHECK-LABEL: @ptr_src_uge_end( 47414da287eSFlorian Hahn; CHECK-NEXT: entry: 475c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]] 476c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]] 477c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]] 478c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_OVERFLOW:%.*]] = icmp ugt ptr [[SRC]], [[SRC_END]] 47914da287eSFlorian Hahn; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]] 48014da287eSFlorian Hahn; CHECK-NEXT: [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[CMP_OVERFLOW]] 48114da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]] 48214da287eSFlorian Hahn; CHECK: trap.bb: 48314da287eSFlorian Hahn; CHECK-NEXT: ret i4 2 48414da287eSFlorian Hahn; CHECK: step.check: 48598e016d9SFlorian Hahn; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i8 [[STEP:%.*]], [[N]] 48698e016d9SFlorian Hahn; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]] 48714da287eSFlorian Hahn; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]] 48814da287eSFlorian Hahn; CHECK: ptr.check: 489c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]] 490c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]] 491c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]] 49214da287eSFlorian Hahn; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]] 49314da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]] 49414da287eSFlorian Hahn; CHECK: exit: 49514da287eSFlorian Hahn; CHECK-NEXT: ret i4 3 49614da287eSFlorian Hahn; 49714da287eSFlorian Hahnentry: 498c5e1ddb6SFlorian Hahn %src.end = getelementptr inbounds i8, ptr %src, i8 %N 499c5e1ddb6SFlorian Hahn %cmp.src.start = icmp ult ptr %src, %lower 500c5e1ddb6SFlorian Hahn %cmp.src.end = icmp uge ptr %src.end, %upper 501c5e1ddb6SFlorian Hahn %cmp.overflow = icmp ugt ptr %src, %src.end 50214da287eSFlorian Hahn %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end 50314da287eSFlorian Hahn %or.precond.1 = or i1 %or.precond.0, %cmp.overflow 50414da287eSFlorian Hahn br i1 %or.precond.1, label %trap.bb, label %step.check 50514da287eSFlorian Hahn 50614da287eSFlorian Hahntrap.bb: 50714da287eSFlorian Hahn ret i4 2 50814da287eSFlorian Hahn 50914da287eSFlorian Hahnstep.check: 5100bcfd4cbSFlorian Hahn %step.pos = icmp uge i8 %step, 0 5110bcfd4cbSFlorian Hahn %step.ult.N = icmp ult i8 %step, %N 51214da287eSFlorian Hahn %and.step = and i1 %step.pos, %step.ult.N 51314da287eSFlorian Hahn br i1 %and.step, label %ptr.check, label %exit 51414da287eSFlorian Hahn 51514da287eSFlorian Hahnptr.check: 516c5e1ddb6SFlorian Hahn %src.step = getelementptr inbounds i8, ptr %src, i8 %step 517c5e1ddb6SFlorian Hahn %cmp.step.start = icmp ult ptr %src.step, %lower 518c5e1ddb6SFlorian Hahn %cmp.step.end = icmp uge ptr %src.step, %upper 51914da287eSFlorian Hahn %or.check = or i1 %cmp.step.start, %cmp.step.end 52014da287eSFlorian Hahn br i1 %or.check, label %trap.bb, label %exit 52114da287eSFlorian Hahn 52214da287eSFlorian Hahnexit: 52314da287eSFlorian Hahn ret i4 3 52414da287eSFlorian Hahn} 52514da287eSFlorian Hahn 52614da287eSFlorian Hahn; N might be negative, meaning %src.end could be < %src! Cannot remove checks! 527c5e1ddb6SFlorian Hahndefine i4 @ptr_N_unsigned_positive(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) { 52814da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_unsigned_positive( 52914da287eSFlorian Hahn; CHECK-NEXT: entry: 530c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]] 531c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]] 532c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]] 53314da287eSFlorian Hahn; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]] 534fbcf8a8cSFlorian Hahn; CHECK-NEXT: [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], false 53514da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]] 53614da287eSFlorian Hahn; CHECK: trap.bb: 53714da287eSFlorian Hahn; CHECK-NEXT: ret i4 2 53814da287eSFlorian Hahn; CHECK: step.check: 53998e016d9SFlorian Hahn; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP:%.*]], [[N]] 54098e016d9SFlorian Hahn; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]] 54114da287eSFlorian Hahn; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]] 54214da287eSFlorian Hahn; CHECK: ptr.check: 543c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]] 544c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]] 545c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]] 54614da287eSFlorian Hahn; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]] 54714da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]] 54814da287eSFlorian Hahn; CHECK: exit: 54914da287eSFlorian Hahn; CHECK-NEXT: ret i4 3 55014da287eSFlorian Hahn; 55114da287eSFlorian Hahnentry: 552c5e1ddb6SFlorian Hahn %src.end = getelementptr inbounds i8, ptr %src, i16 %N 553c5e1ddb6SFlorian Hahn %cmp.src.start = icmp ult ptr %src, %lower 554c5e1ddb6SFlorian Hahn %cmp.src.end = icmp uge ptr %src.end, %upper 55514da287eSFlorian Hahn %N.neg = icmp ult i16 %N, 0 55614da287eSFlorian Hahn %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end 55714da287eSFlorian Hahn %or.precond.1 = or i1 %or.precond.0, %N.neg 55814da287eSFlorian Hahn br i1 %or.precond.1, label %trap.bb, label %step.check 55914da287eSFlorian Hahn 56014da287eSFlorian Hahntrap.bb: 56114da287eSFlorian Hahn ret i4 2 56214da287eSFlorian Hahn 56314da287eSFlorian Hahnstep.check: 56414da287eSFlorian Hahn %step.pos = icmp uge i16 %step, 0 56514da287eSFlorian Hahn %step.ult.N = icmp ult i16 %step, %N 56614da287eSFlorian Hahn %and.step = and i1 %step.pos, %step.ult.N 56714da287eSFlorian Hahn br i1 %and.step, label %ptr.check, label %exit 56814da287eSFlorian Hahn 56914da287eSFlorian Hahnptr.check: 570c5e1ddb6SFlorian Hahn %src.step = getelementptr inbounds i8, ptr %src, i16 %step 571c5e1ddb6SFlorian Hahn %cmp.step.start = icmp ult ptr %src.step, %lower 572c5e1ddb6SFlorian Hahn %cmp.step.end = icmp uge ptr %src.step, %upper 57314da287eSFlorian Hahn %or.check = or i1 %cmp.step.start, %cmp.step.end 57414da287eSFlorian Hahn br i1 %or.check, label %trap.bb, label %exit 57514da287eSFlorian Hahn 57614da287eSFlorian Hahnexit: 57714da287eSFlorian Hahn ret i4 3 57814da287eSFlorian Hahn} 57914da287eSFlorian Hahn 580c5e1ddb6SFlorian Hahndefine i4 @ptr_N_signed_positive_assume(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) { 58114da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_signed_positive_assume( 58214da287eSFlorian Hahn; CHECK-NEXT: entry: 583c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]] 584c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]] 585c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]] 58614da287eSFlorian Hahn; CHECK-NEXT: [[N_NEG:%.*]] = icmp slt i16 [[N]], 0 58714da287eSFlorian Hahn; CHECK-NEXT: call void @llvm.assume(i1 [[N_NEG]]) 58814da287eSFlorian Hahn; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]] 58914da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]] 59014da287eSFlorian Hahn; CHECK: trap.bb: 59114da287eSFlorian Hahn; CHECK-NEXT: ret i4 2 59214da287eSFlorian Hahn; CHECK: step.check: 59398e016d9SFlorian Hahn; CHECK-NEXT: [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP:%.*]], [[N]] 59498e016d9SFlorian Hahn; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]] 59514da287eSFlorian Hahn; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]] 59614da287eSFlorian Hahn; CHECK: ptr.check: 597c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]] 598c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]] 599c5e1ddb6SFlorian Hahn; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]] 60006f3ef66SFlorian Hahn; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]] 60114da287eSFlorian Hahn; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]] 60214da287eSFlorian Hahn; CHECK: exit: 60314da287eSFlorian Hahn; CHECK-NEXT: ret i4 3 60414da287eSFlorian Hahn; 60514da287eSFlorian Hahnentry: 606c5e1ddb6SFlorian Hahn %src.end = getelementptr inbounds i8, ptr %src, i16 %N 607c5e1ddb6SFlorian Hahn %cmp.src.start = icmp ult ptr %src, %lower 608c5e1ddb6SFlorian Hahn %cmp.src.end = icmp uge ptr %src.end, %upper 60914da287eSFlorian Hahn %N.neg = icmp slt i16 %N, 0 61014da287eSFlorian Hahn call void @llvm.assume(i1 %N.neg) 61114da287eSFlorian Hahn %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end 61214da287eSFlorian Hahn br i1 %or.precond.0, label %trap.bb, label %step.check 61314da287eSFlorian Hahn 61414da287eSFlorian Hahntrap.bb: 61514da287eSFlorian Hahn ret i4 2 61614da287eSFlorian Hahn 61714da287eSFlorian Hahnstep.check: 61814da287eSFlorian Hahn %step.pos = icmp uge i16 %step, 0 61914da287eSFlorian Hahn %step.ult.N = icmp ult i16 %step, %N 62014da287eSFlorian Hahn %and.step = and i1 %step.pos, %step.ult.N 62114da287eSFlorian Hahn br i1 %and.step, label %ptr.check, label %exit 62214da287eSFlorian Hahn 62314da287eSFlorian Hahnptr.check: 624c5e1ddb6SFlorian Hahn %src.step = getelementptr inbounds i8, ptr %src, i16 %step 625c5e1ddb6SFlorian Hahn %cmp.step.start = icmp ult ptr %src.step, %lower 626c5e1ddb6SFlorian Hahn %cmp.step.end = icmp uge ptr %src.step, %upper 62714da287eSFlorian Hahn %or.check = or i1 %cmp.step.start, %cmp.step.end 62814da287eSFlorian Hahn br i1 %or.check, label %trap.bb, label %exit 62914da287eSFlorian Hahn 63014da287eSFlorian Hahnexit: 63114da287eSFlorian Hahn ret i4 3 63214da287eSFlorian Hahn} 63310223c72SNikita Popov 63410223c72SNikita Popovdefine i1 @test_nusw(ptr %p, i32 %x, i32 %y) { 63510223c72SNikita Popov; CHECK-LABEL: @test_nusw( 63610223c72SNikita Popov; CHECK-NEXT: [[X_EXT:%.*]] = zext i32 [[X:%.*]] to i64 63710223c72SNikita Popov; CHECK-NEXT: [[Y_EXT:%.*]] = zext i32 [[Y:%.*]] to i64 63810223c72SNikita Popov; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X_EXT]], [[Y_EXT]] 63910223c72SNikita Popov; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]]) 64010223c72SNikita Popov; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr nusw i8, ptr [[P:%.*]], i64 [[X_EXT]] 64110223c72SNikita Popov; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nusw i8, ptr [[P]], i64 [[Y_EXT]] 64210223c72SNikita Popov; CHECK-NEXT: ret i1 true 64310223c72SNikita Popov; 64410223c72SNikita Popov %x.ext = zext i32 %x to i64 64510223c72SNikita Popov %y.ext = zext i32 %y to i64 64610223c72SNikita Popov %cmp1 = icmp ugt i64 %x.ext, %y.ext 64710223c72SNikita Popov call void @llvm.assume(i1 %cmp1) 64810223c72SNikita Popov %gep.x = getelementptr nusw i8, ptr %p, i64 %x.ext 64910223c72SNikita Popov %gep.y = getelementptr nusw i8, ptr %p, i64 %y.ext 65010223c72SNikita Popov %cmp2 = icmp ugt ptr %gep.x, %gep.y 65110223c72SNikita Popov ret i1 %cmp2 65210223c72SNikita Popov} 65310223c72SNikita Popov 65410223c72SNikita Popovdefine i1 @test_nusw_nested(ptr %p, i32 %x, i32 %y) { 65510223c72SNikita Popov; CHECK-LABEL: @test_nusw_nested( 65610223c72SNikita Popov; CHECK-NEXT: [[X_EXT:%.*]] = zext i32 [[X:%.*]] to i64 65710223c72SNikita Popov; CHECK-NEXT: [[Y_EXT:%.*]] = zext i32 [[Y:%.*]] to i64 65810223c72SNikita Popov; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X_EXT]], [[Y_EXT]] 65910223c72SNikita Popov; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]]) 66010223c72SNikita Popov; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr nusw i8, ptr [[P:%.*]], i64 [[X_EXT]] 66110223c72SNikita Popov; CHECK-NEXT: [[GEP_X1:%.*]] = getelementptr nusw i8, ptr [[GEP_X]], i64 1 66210223c72SNikita Popov; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nusw i8, ptr [[P]], i64 [[Y_EXT]] 66310223c72SNikita Popov; CHECK-NEXT: ret i1 true 66410223c72SNikita Popov; 66510223c72SNikita Popov %x.ext = zext i32 %x to i64 66610223c72SNikita Popov %y.ext = zext i32 %y to i64 66710223c72SNikita Popov %cmp1 = icmp ugt i64 %x.ext, %y.ext 66810223c72SNikita Popov call void @llvm.assume(i1 %cmp1) 66910223c72SNikita Popov %gep.x = getelementptr nusw i8, ptr %p, i64 %x.ext 67010223c72SNikita Popov %gep.x1 = getelementptr nusw i8, ptr %gep.x, i64 1 67110223c72SNikita Popov %gep.y = getelementptr nusw i8, ptr %p, i64 %y.ext 67210223c72SNikita Popov %cmp2 = icmp ugt ptr %gep.x1, %gep.y 67310223c72SNikita Popov ret i1 %cmp2 67410223c72SNikita Popov} 67510223c72SNikita Popov 67610223c72SNikita Popovdefine i1 @test_missing_nusw(ptr %p, i32 %x, i32 %y) { 67710223c72SNikita Popov; CHECK-LABEL: @test_missing_nusw( 67810223c72SNikita Popov; CHECK-NEXT: [[X_EXT:%.*]] = zext i32 [[X:%.*]] to i64 67910223c72SNikita Popov; CHECK-NEXT: [[Y_EXT:%.*]] = zext i32 [[Y:%.*]] to i64 68010223c72SNikita Popov; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X_EXT]], [[Y_EXT]] 68110223c72SNikita Popov; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]]) 68210223c72SNikita Popov; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr nusw i8, ptr [[P:%.*]], i64 [[X_EXT]] 68310223c72SNikita Popov; CHECK-NEXT: [[GEP_X1:%.*]] = getelementptr i8, ptr [[GEP_X]], i64 1 68410223c72SNikita Popov; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nusw i8, ptr [[P]], i64 [[Y_EXT]] 68510223c72SNikita Popov; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt ptr [[GEP_X1]], [[GEP_Y]] 68610223c72SNikita Popov; CHECK-NEXT: ret i1 [[CMP2]] 68710223c72SNikita Popov; 68810223c72SNikita Popov %x.ext = zext i32 %x to i64 68910223c72SNikita Popov %y.ext = zext i32 %y to i64 69010223c72SNikita Popov %cmp1 = icmp ugt i64 %x.ext, %y.ext 69110223c72SNikita Popov call void @llvm.assume(i1 %cmp1) 69210223c72SNikita Popov %gep.x = getelementptr nusw i8, ptr %p, i64 %x.ext 69310223c72SNikita Popov %gep.x1 = getelementptr i8, ptr %gep.x, i64 1 69410223c72SNikita Popov %gep.y = getelementptr nusw i8, ptr %p, i64 %y.ext 69510223c72SNikita Popov %cmp2 = icmp ugt ptr %gep.x1, %gep.y 69610223c72SNikita Popov ret i1 %cmp2 69710223c72SNikita Popov} 69875af6283SNikita Popov 69975af6283SNikita Popovdefine i1 @test_nuw(ptr %p, i64 %x, i64 %y) { 70075af6283SNikita Popov; CHECK-LABEL: @test_nuw( 70175af6283SNikita Popov; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]] 70275af6283SNikita Popov; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]]) 70375af6283SNikita Popov; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[X]] 70475af6283SNikita Popov; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[Y]] 705*a608607fSNikita Popov; CHECK-NEXT: ret i1 true 70675af6283SNikita Popov; 70775af6283SNikita Popov %cmp1 = icmp ugt i64 %x, %y 70875af6283SNikita Popov call void @llvm.assume(i1 %cmp1) 70975af6283SNikita Popov %gep.x = getelementptr nuw i8, ptr %p, i64 %x 71075af6283SNikita Popov %gep.y = getelementptr nuw i8, ptr %p, i64 %y 71175af6283SNikita Popov %cmp2 = icmp ugt ptr %gep.x, %gep.y 71275af6283SNikita Popov ret i1 %cmp2 71375af6283SNikita Popov} 71475af6283SNikita Popov 71575af6283SNikita Popovdefine i1 @test_nuw_nested(ptr %p, i64 %x, i64 %y) { 71675af6283SNikita Popov; CHECK-LABEL: @test_nuw_nested( 71775af6283SNikita Popov; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]] 71875af6283SNikita Popov; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]]) 71975af6283SNikita Popov; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[X]] 72075af6283SNikita Popov; CHECK-NEXT: [[GEP_X1:%.*]] = getelementptr nuw i8, ptr [[GEP_X]], i64 1 72175af6283SNikita Popov; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[Y]] 722*a608607fSNikita Popov; CHECK-NEXT: ret i1 true 72375af6283SNikita Popov; 72475af6283SNikita Popov %cmp1 = icmp ugt i64 %x, %y 72575af6283SNikita Popov call void @llvm.assume(i1 %cmp1) 72675af6283SNikita Popov %gep.x = getelementptr nuw i8, ptr %p, i64 %x 72775af6283SNikita Popov %gep.x1 = getelementptr nuw i8, ptr %gep.x, i64 1 72875af6283SNikita Popov %gep.y = getelementptr nuw i8, ptr %p, i64 %y 72975af6283SNikita Popov %cmp2 = icmp ugt ptr %gep.x1, %gep.y 73075af6283SNikita Popov ret i1 %cmp2 73175af6283SNikita Popov} 73275af6283SNikita Popov 73375af6283SNikita Popovdefine i1 @test_nuw_nested_missing_nuw(ptr %p, i64 %x, i64 %y) { 73475af6283SNikita Popov; CHECK-LABEL: @test_nuw_nested_missing_nuw( 73575af6283SNikita Popov; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]] 73675af6283SNikita Popov; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]]) 73775af6283SNikita Popov; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[X]] 73875af6283SNikita Popov; CHECK-NEXT: [[GEP_X1:%.*]] = getelementptr nuw i8, ptr [[GEP_X]], i64 1 73975af6283SNikita Popov; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[Y]] 74075af6283SNikita Popov; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt ptr [[GEP_X1]], [[GEP_Y]] 74175af6283SNikita Popov; CHECK-NEXT: ret i1 [[CMP2]] 74275af6283SNikita Popov; 74375af6283SNikita Popov %cmp1 = icmp ugt i64 %x, %y 74475af6283SNikita Popov call void @llvm.assume(i1 %cmp1) 74575af6283SNikita Popov %gep.x = getelementptr i8, ptr %p, i64 %x 74675af6283SNikita Popov %gep.x1 = getelementptr nuw i8, ptr %gep.x, i64 1 74775af6283SNikita Popov %gep.y = getelementptr nuw i8, ptr %p, i64 %y 74875af6283SNikita Popov %cmp2 = icmp ugt ptr %gep.x1, %gep.y 74975af6283SNikita Popov ret i1 %cmp2 75075af6283SNikita Popov} 75175af6283SNikita Popov 75275af6283SNikita Popovdefine i1 @test_nuw_incorrect_precondition(ptr %p, i64 %x, i64 %y) { 75375af6283SNikita Popov; CHECK-LABEL: @test_nuw_incorrect_precondition( 75475af6283SNikita Popov; CHECK-NEXT: [[CMP1:%.*]] = icmp uge i64 [[X:%.*]], [[Y:%.*]] 75575af6283SNikita Popov; CHECK-NEXT: call void @llvm.assume(i1 [[CMP1]]) 75675af6283SNikita Popov; CHECK-NEXT: [[GEP_X:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[X]] 75775af6283SNikita Popov; CHECK-NEXT: [[GEP_Y:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[Y]] 75875af6283SNikita Popov; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt ptr [[GEP_X]], [[GEP_Y]] 75975af6283SNikita Popov; CHECK-NEXT: ret i1 [[CMP2]] 76075af6283SNikita Popov; 76175af6283SNikita Popov %cmp1 = icmp uge i64 %x, %y 76275af6283SNikita Popov call void @llvm.assume(i1 %cmp1) 76375af6283SNikita Popov %gep.x = getelementptr nuw i8, ptr %p, i64 %x 76475af6283SNikita Popov %gep.y = getelementptr nuw i8, ptr %p, i64 %y 76575af6283SNikita Popov %cmp2 = icmp ugt ptr %gep.x, %gep.y 76675af6283SNikita Popov ret i1 %cmp2 76775af6283SNikita Popov} 768