651 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s3 4declare void @llvm.assume(i1 noundef) #05 6define i1 @gep_constant_positive_index(ptr %dst, ptr %lower, ptr %upper) {7; CHECK-LABEL: @gep_constant_positive_index(8; CHECK-NEXT: [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 49; CHECK-NEXT: [[PRE_DST_LOWER:%.*]] = icmp sge ptr [[DST]], [[LOWER:%.*]]10; CHECK-NEXT: [[PRE_DST_UPPER:%.*]] = icmp slt ptr [[DST_ADD_4]], [[UPPER:%.*]]11; CHECK-NEXT: [[AND:%.*]] = and i1 [[PRE_DST_LOWER]], [[PRE_DST_UPPER]]12; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]13; CHECK: then:14; CHECK-NEXT: [[CMP_DST_UPPER:%.*]] = icmp slt ptr [[DST]], [[UPPER]]15; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[CMP_DST_UPPER]]16; CHECK-NEXT: [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 317; CHECK-NEXT: [[CMP_DST_ADD_3_LOWER:%.*]] = icmp sge ptr [[DST_ADD_3]], [[LOWER]]18; CHECK-NEXT: [[CMP_DST_ADD_3_UPPER:%.*]] = icmp slt ptr [[DST_ADD_3]], [[UPPER]]19; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_DST_ADD_3_LOWER]]20; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[RES_2]], [[CMP_DST_ADD_3_UPPER]]21; CHECK-NEXT: [[CMP_DST_ADD_4_LOWER:%.*]] = icmp sge ptr [[DST_ADD_4]], [[LOWER]]22; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[CMP_DST_ADD_4_LOWER]]23; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true24; CHECK-NEXT: [[DST_ADD_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 525; CHECK-NEXT: [[CMP_DST_ADD_5_LOWER:%.*]] = icmp sge ptr [[DST_ADD_5]], [[LOWER]]26; CHECK-NEXT: [[CMP_DST_ADD_5_UPPER:%.*]] = icmp slt ptr [[DST_ADD_5]], [[UPPER]]27; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[CMP_DST_ADD_5_LOWER]]28; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[CMP_DST_ADD_5_UPPER]]29; CHECK-NEXT: ret i1 [[RES_7]]30; CHECK: else:31; CHECK-NEXT: ret i1 false32;33 %dst.add.4 = getelementptr inbounds i8, ptr %dst, i64 434 %pre.dst.lower = icmp sge ptr %dst, %lower35 %pre.dst.upper = icmp slt ptr %dst.add.4, %upper36 %and = and i1 %pre.dst.lower, %pre.dst.upper37 br i1 %and, label %then, label %else38 39then:40 %cmp.dst.lower = icmp sge ptr %dst, %lower41 %cmp.dst.upper = icmp slt ptr %dst, %upper42 %res.1 = xor i1 %cmp.dst.lower, %cmp.dst.upper43 %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 344 %cmp.dst.add.3.lower = icmp sge ptr %dst.add.3, %lower45 %cmp.dst.add.3.upper = icmp slt ptr %dst.add.3, %upper46 %res.2 = xor i1 %res.1, %cmp.dst.add.3.lower47 %res.3 = xor i1 %res.2, %cmp.dst.add.3.upper48 %cmp.dst.add.4.lower = icmp sge ptr %dst.add.4, %lower49 %cmp.dst.add.4.upper = icmp slt ptr %dst.add.4, %upper50 %res.4 = xor i1 %res.3, %cmp.dst.add.4.lower51 %res.5 = xor i1 %res.4, %cmp.dst.add.4.upper52 %dst.add.5 = getelementptr inbounds i8, ptr %dst, i64 553 %cmp.dst.add.5.lower = icmp sge ptr %dst.add.5, %lower54 %cmp.dst.add.5.upper = icmp slt ptr %dst.add.5, %upper55 %res.6 = xor i1 %res.5, %cmp.dst.add.5.lower56 %res.7 = xor i1 %res.6, %cmp.dst.add.5.upper57 ret i1 %res.758 59else:60 ret i1 false61}62 63define i1 @gep_constant_negative_index(ptr %dst, ptr %lower, ptr %upper) {64; CHECK-LABEL: @gep_constant_negative_index(65; CHECK-NEXT: [[DST_SUB_4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 -466; CHECK-NEXT: [[PRE_DST_LOWER:%.*]] = icmp sge ptr [[DST]], [[LOWER:%.*]]67; CHECK-NEXT: [[PRE_DST_UPPER:%.*]] = icmp slt ptr [[DST_SUB_4]], [[UPPER:%.*]]68; CHECK-NEXT: [[AND:%.*]] = and i1 [[PRE_DST_LOWER]], [[PRE_DST_UPPER]]69; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]70; CHECK: then:71; CHECK-NEXT: [[CMP_DST_UPPER:%.*]] = icmp slt ptr [[DST]], [[UPPER]]72; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[CMP_DST_UPPER]]73; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -374; CHECK-NEXT: [[CMP_DST_SUB_3_LOWER:%.*]] = icmp sge ptr [[DST_SUB_3]], [[LOWER]]75; CHECK-NEXT: [[CMP_DST_SUB_3_UPPER:%.*]] = icmp slt ptr [[DST_SUB_3]], [[UPPER]]76; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_DST_SUB_3_LOWER]]77; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[RES_2]], [[CMP_DST_SUB_3_UPPER]]78; CHECK-NEXT: [[CMP_DST_SUB_4_LOWER:%.*]] = icmp sge ptr [[DST_SUB_4]], [[LOWER]]79; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[CMP_DST_SUB_4_LOWER]]80; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true81; CHECK-NEXT: [[DST_SUB_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -582; CHECK-NEXT: [[CMP_DST_SUB_5_LOWER:%.*]] = icmp sge ptr [[DST_SUB_5]], [[LOWER]]83; CHECK-NEXT: [[CMP_DST_SUB_5_UPPER:%.*]] = icmp slt ptr [[DST_SUB_5]], [[UPPER]]84; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[CMP_DST_SUB_5_LOWER]]85; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[CMP_DST_SUB_5_UPPER]]86; CHECK-NEXT: ret i1 [[RES_7]]87; CHECK: else:88; CHECK-NEXT: [[ELSE_CMP_DST_LOWER:%.*]] = icmp sge ptr [[DST]], [[LOWER]]89; CHECK-NEXT: [[ELSE_CMP_DST_UPPER:%.*]] = icmp slt ptr [[DST]], [[UPPER]]90; CHECK-NEXT: [[ELSE_RES_1:%.*]] = xor i1 [[ELSE_CMP_DST_LOWER]], [[ELSE_CMP_DST_UPPER]]91; CHECK-NEXT: [[ELSE_DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -392; CHECK-NEXT: [[ELSE_CMP_DST_SUB_3_LOWER:%.*]] = icmp sge ptr [[ELSE_DST_SUB_3]], [[LOWER]]93; CHECK-NEXT: [[ELSE_CMP_DST_SUB_3_UPPER:%.*]] = icmp slt ptr [[ELSE_DST_SUB_3]], [[UPPER]]94; CHECK-NEXT: [[ELSE_RES_2:%.*]] = xor i1 [[ELSE_RES_1]], [[ELSE_CMP_DST_SUB_3_LOWER]]95; CHECK-NEXT: [[ELSE_RES_3:%.*]] = xor i1 [[ELSE_RES_2]], [[ELSE_CMP_DST_SUB_3_UPPER]]96; CHECK-NEXT: [[ELSE_CMP_DST_SUB_4_LOWER:%.*]] = icmp sge ptr [[DST_SUB_4]], [[LOWER]]97; CHECK-NEXT: [[ELSE_CMP_DST_SUB_4_UPPER:%.*]] = icmp slt ptr [[DST_SUB_4]], [[UPPER]]98; CHECK-NEXT: [[ELSE_RES_4:%.*]] = xor i1 [[ELSE_RES_3]], [[ELSE_CMP_DST_SUB_4_LOWER]]99; CHECK-NEXT: [[ELSE_RES_5:%.*]] = xor i1 [[ELSE_RES_4]], [[ELSE_CMP_DST_SUB_4_UPPER]]100; CHECK-NEXT: [[ELSE_DST_SUB_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -5101; CHECK-NEXT: [[ELSE_CMP_DST_SUB_5_LOWER:%.*]] = icmp sge ptr [[ELSE_DST_SUB_5]], [[LOWER]]102; CHECK-NEXT: [[ELSE_CMP_DST_SUB_5_UPPER:%.*]] = icmp slt ptr [[ELSE_DST_SUB_5]], [[UPPER]]103; CHECK-NEXT: [[ELSE_RES_6:%.*]] = xor i1 [[ELSE_RES_5]], [[ELSE_CMP_DST_SUB_5_LOWER]]104; CHECK-NEXT: [[ELSE_RES_7:%.*]] = xor i1 [[ELSE_RES_6]], [[ELSE_CMP_DST_SUB_5_UPPER]]105; CHECK-NEXT: ret i1 [[ELSE_RES_7]]106;107 %dst.sub.4 = getelementptr inbounds i8, ptr %dst, i64 -4108 %pre.dst.lower = icmp sge ptr %dst, %lower109 %pre.dst.upper = icmp slt ptr %dst.sub.4, %upper110 %and = and i1 %pre.dst.lower, %pre.dst.upper111 br i1 %and, label %then, label %else112 113then:114 %cmp.dst.lower = icmp sge ptr %dst, %lower115 %cmp.dst.upper = icmp slt ptr %dst, %upper116 %res.1 = xor i1 %cmp.dst.lower, %cmp.dst.upper117 %dst.sub.3 = getelementptr inbounds i8, ptr %dst, i64 -3118 %cmp.dst.sub.3.lower = icmp sge ptr %dst.sub.3, %lower119 %cmp.dst.sub.3.upper = icmp slt ptr %dst.sub.3, %upper120 %res.2 = xor i1 %res.1, %cmp.dst.sub.3.lower121 %res.3 = xor i1 %res.2, %cmp.dst.sub.3.upper122 %cmp.dst.sub.4.lower = icmp sge ptr %dst.sub.4, %lower123 %cmp.dst.sub.4.upper = icmp slt ptr %dst.sub.4, %upper124 %res.4 = xor i1 %res.3, %cmp.dst.sub.4.lower125 %res.5 = xor i1 %res.4, %cmp.dst.sub.4.upper126 %dst.sub.5 = getelementptr inbounds i8, ptr %dst, i64 -5127 %cmp.dst.sub.5.lower = icmp sge ptr %dst.sub.5, %lower128 %cmp.dst.sub.5.upper = icmp slt ptr %dst.sub.5, %upper129 %res.6 = xor i1 %res.5, %cmp.dst.sub.5.lower130 %res.7 = xor i1 %res.6, %cmp.dst.sub.5.upper131 ret i1 %res.7132 133else:134 %else.cmp.dst.lower = icmp sge ptr %dst, %lower135 %else.cmp.dst.upper = icmp slt ptr %dst, %upper136 %else.res.1 = xor i1 %else.cmp.dst.lower, %else.cmp.dst.upper137 %else.dst.sub.3 = getelementptr inbounds i8, ptr %dst, i64 -3138 %else.cmp.dst.sub.3.lower = icmp sge ptr %else.dst.sub.3, %lower139 %else.cmp.dst.sub.3.upper = icmp slt ptr %else.dst.sub.3, %upper140 %else.res.2 = xor i1 %else.res.1, %else.cmp.dst.sub.3.lower141 %else.res.3 = xor i1 %else.res.2, %else.cmp.dst.sub.3.upper142 %else.cmp.dst.sub.4.lower = icmp sge ptr %dst.sub.4, %lower143 %else.cmp.dst.sub.4.upper = icmp slt ptr %dst.sub.4, %upper144 %else.res.4 = xor i1 %else.res.3, %else.cmp.dst.sub.4.lower145 %else.res.5 = xor i1 %else.res.4, %else.cmp.dst.sub.4.upper146 %else.dst.sub.5 = getelementptr inbounds i8, ptr %dst, i64 -5147 %else.cmp.dst.sub.5.lower = icmp sge ptr %else.dst.sub.5, %lower148 %else.cmp.dst.sub.5.upper = icmp slt ptr %else.dst.sub.5, %upper149 %else.res.6 = xor i1 %else.res.5, %else.cmp.dst.sub.5.lower150 %else.res.7 = xor i1 %else.res.6, %else.cmp.dst.sub.5.upper151 ret i1 %else.res.7152}153 154define i4 @ptr_N_signed_positive_explicit_check_constant_step(ptr %src, ptr %lower, ptr %upper, i16 %N) {155; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step(156; CHECK-NEXT: entry:157; CHECK-NEXT: [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0158; CHECK-NEXT: br i1 [[N_POS]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]159; CHECK: entry.1:160; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N]]161; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]162; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]163; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]164; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]165; CHECK: trap.bb:166; CHECK-NEXT: ret i4 2167; CHECK: step.check:168; CHECK-NEXT: [[STEP_SLT_N:%.*]] = icmp slt i16 1, [[N]]169; CHECK-NEXT: br i1 [[STEP_SLT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]170; CHECK: ptr.check:171; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1172; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]173; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]174; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]175; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]176; CHECK: exit:177; CHECK-NEXT: ret i4 3178;179entry:180 %N.pos = icmp sge i16 %N, 0181 br i1 %N.pos, label %entry.1, label %trap.bb182 183entry.1:184 %src.end = getelementptr inbounds i8, ptr %src, i16 %N185 %cmp.src.start = icmp slt ptr %src, %lower186 %cmp.src.end = icmp sge ptr %src.end, %upper187 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end188 br i1 %or.precond.0, label %trap.bb, label %step.check189 190trap.bb:191 ret i4 2192 193step.check:194 %step.slt.N = icmp slt i16 1, %N195 br i1 %step.slt.N, label %ptr.check, label %exit196 197ptr.check:198 %src.step = getelementptr inbounds i8, ptr %src, i16 1199 %cmp.step.start = icmp slt ptr %src.step, %lower200 %cmp.step.end = icmp sge ptr %src.step, %upper201 %or.check = or i1 %cmp.step.start, %cmp.step.end202 br i1 %or.check, label %trap.bb, label %exit203 204exit:205 ret i4 3206}207 208; Same as ptr_N_signed_positive_explicit_check_constant_step, but without inbounds.209define i4 @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(ptr %src, ptr %lower, ptr %upper, i16 %N) {210; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(211; CHECK-NEXT: entry:212; CHECK-NEXT: [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0213; CHECK-NEXT: br i1 [[N_POS]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]214; CHECK: entry.1:215; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr i8, ptr [[SRC:%.*]], i16 [[N]]216; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]217; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]218; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]219; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]220; CHECK: trap.bb:221; CHECK-NEXT: ret i4 2222; CHECK: step.check:223; CHECK-NEXT: [[STEP_SLT_N:%.*]] = icmp slt i16 1, [[N]]224; CHECK-NEXT: br i1 [[STEP_SLT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]225; CHECK: ptr.check:226; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr i8, ptr [[SRC]], i16 1227; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]228; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]229; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]230; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]231; CHECK: exit:232; CHECK-NEXT: ret i4 3233;234entry:235 %N.pos = icmp sge i16 %N, 0236 br i1 %N.pos, label %entry.1, label %trap.bb237 238entry.1:239 %src.end = getelementptr i8, ptr %src, i16 %N240 %cmp.src.start = icmp slt ptr %src, %lower241 %cmp.src.end = icmp sge ptr %src.end, %upper242 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end243 br i1 %or.precond.0, label %trap.bb, label %step.check244 245trap.bb:246 ret i4 2247 248step.check:249 %step.slt.N = icmp slt i16 1, %N250 br i1 %step.slt.N, label %ptr.check, label %exit251 252ptr.check:253 %src.step = getelementptr i8, ptr %src, i16 1254 %cmp.step.start = icmp slt ptr %src.step, %lower255 %cmp.step.end = icmp sge ptr %src.step, %upper256 %or.check = or i1 %cmp.step.start, %cmp.step.end257 br i1 %or.check, label %trap.bb, label %exit258 259exit:260 ret i4 3261}262 263define i4 @ptr_N_and_step_signed_positive_explicit_check_constant_step(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {264; CHECK-LABEL: @ptr_N_and_step_signed_positive_explicit_check_constant_step(265; CHECK-NEXT: entry:266; CHECK-NEXT: [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0267; CHECK-NEXT: [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0268; CHECK-NEXT: [[AND_1:%.*]] = and i1 [[N_POS]], [[STEP_POS]]269; CHECK-NEXT: br i1 [[AND_1]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]270; CHECK: entry.1:271; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N]]272; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]273; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]274; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]275; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]276; CHECK: trap.bb:277; CHECK-NEXT: ret i4 2278; CHECK: step.check:279; CHECK-NEXT: [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]280; CHECK-NEXT: [[AND_2:%.*]] = and i1 true, [[STEP_SLT_N]]281; CHECK-NEXT: br i1 [[AND_2]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]282; CHECK: ptr.check:283; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1284; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]285; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]286; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]287; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]288; CHECK: exit:289; CHECK-NEXT: ret i4 3290;291entry:292 %N.pos = icmp sge i16 %N, 0293 %step.pos = icmp sge i16 %step, 0294 %and.1 = and i1 %N.pos, %step.pos295 br i1 %and.1, label %entry.1, label %trap.bb296 297entry.1:298 %src.end = getelementptr inbounds i8, ptr %src, i16 %N299 %cmp.src.start = icmp slt ptr %src, %lower300 %cmp.src.end = icmp sge ptr %src.end, %upper301 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end302 br i1 %or.precond.0, label %trap.bb, label %step.check303 304trap.bb:305 ret i4 2306 307step.check:308 %step.sge.0 = icmp sge i16 %step, 0309 %step.slt.N = icmp slt i16 %step, %N310 %and.2 = and i1 %step.sge.0, %step.slt.N311 br i1 %and.2, label %ptr.check, label %exit312 313ptr.check:314 %src.step = getelementptr inbounds i8, ptr %src, i16 1315 %cmp.step.start = icmp slt ptr %src.step, %lower316 %cmp.step.end = icmp sge ptr %src.step, %upper317 %or.check = or i1 %cmp.step.start, %cmp.step.end318 br i1 %or.check, label %trap.bb, label %exit319 320exit:321 ret i4 3322}323 324define i4 @ptr_N_and_step_signed_positive_unsigned_checks_only(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {325; CHECK-LABEL: @ptr_N_and_step_signed_positive_unsigned_checks_only(326; CHECK-NEXT: entry:327; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]328; CHECK-NEXT: [[NO_OVERFLOW:%.*]] = icmp sle ptr [[SRC]], [[SRC_END]]329; CHECK-NEXT: br i1 [[NO_OVERFLOW]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]330; CHECK: entry.1:331; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]332; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]333; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]334; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]335; CHECK: trap.bb:336; CHECK-NEXT: ret i4 2337; CHECK: step.check:338; CHECK-NEXT: [[STEP_SGE_0:%.*]] = icmp sge i16 [[STEP:%.*]], 0339; CHECK-NEXT: [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]340; CHECK-NEXT: [[AND_2:%.*]] = and i1 [[STEP_SGE_0]], [[STEP_SLT_N]]341; CHECK-NEXT: br i1 [[AND_2]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]342; CHECK: ptr.check:343; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1344; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]345; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]346; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]347; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]348; CHECK: exit:349; CHECK-NEXT: ret i4 3350;351entry:352 %src.end = getelementptr inbounds i8, ptr %src, i16 %N353 %no.overflow = icmp sle ptr %src, %src.end354 br i1 %no.overflow, label %entry.1, label %trap.bb355 356entry.1:357 %cmp.src.start = icmp slt ptr %src, %lower358 %cmp.src.end = icmp sge ptr %src.end, %upper359 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end360 br i1 %or.precond.0, label %trap.bb, label %step.check361 362trap.bb:363 ret i4 2364 365step.check:366 %step.sge.0 = icmp sge i16 %step, 0367 %step.slt.N = icmp slt i16 %step, %N368 %and.2 = and i1 %step.sge.0, %step.slt.N369 br i1 %and.2, label %ptr.check, label %exit370 371ptr.check:372 %src.step = getelementptr inbounds i8, ptr %src, i16 1373 %cmp.step.start = icmp slt ptr %src.step, %lower374 %cmp.step.end = icmp sge ptr %src.step, %upper375 %or.check = or i1 %cmp.step.start, %cmp.step.end376 br i1 %or.check, label %trap.bb, label %exit377 378exit:379 ret i4 3380}381 382define i4 @ptr_N_signed_positive(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {383; CHECK-LABEL: @ptr_N_signed_positive(384; CHECK-NEXT: entry:385; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]386; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]387; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]388; CHECK-NEXT: [[N_NEG:%.*]] = icmp slt i16 [[N]], 0389; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]390; CHECK-NEXT: [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[N_NEG]]391; CHECK-NEXT: br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]392; CHECK: trap.bb:393; CHECK-NEXT: ret i4 2394; CHECK: step.check:395; CHECK-NEXT: [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0396; CHECK-NEXT: [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]397; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]398; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]399; CHECK: ptr.check:400; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]401; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]402; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]403; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]404; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]405; CHECK: exit:406; CHECK-NEXT: ret i4 3407;408entry:409 %src.end = getelementptr inbounds i8, ptr %src, i16 %N410 %cmp.src.start = icmp slt ptr %src, %lower411 %cmp.src.end = icmp sge ptr %src.end, %upper412 %N.neg = icmp slt i16 %N, 0413 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end414 %or.precond.1 = or i1 %or.precond.0, %N.neg415 br i1 %or.precond.1, label %trap.bb, label %step.check416 417trap.bb:418 ret i4 2419 420step.check:421 %step.pos = icmp sge i16 %step, 0422 %step.slt.N = icmp slt i16 %step, %N423 %and.step = and i1 %step.pos, %step.slt.N424 br i1 %and.step, label %ptr.check, label %exit425 426ptr.check:427 %src.step = getelementptr inbounds i8, ptr %src, i16 %step428 %cmp.step.start = icmp slt ptr %src.step, %lower429 %cmp.step.end = icmp sge ptr %src.step, %upper430 %or.check = or i1 %cmp.step.start, %cmp.step.end431 br i1 %or.check, label %trap.bb, label %exit432 433exit:434 ret i4 3435}436 437define i4 @ptr_N_could_be_negative(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) {438; CHECK-LABEL: @ptr_N_could_be_negative(439; CHECK-NEXT: entry:440; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]441; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]442; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]443; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]444; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]445; CHECK: trap.bb:446; CHECK-NEXT: ret i4 2447; CHECK: step.check:448; CHECK-NEXT: [[STEP_POS:%.*]] = icmp sge i8 [[STEP:%.*]], 0449; CHECK-NEXT: [[STEP_SLT_N:%.*]] = icmp slt i8 [[STEP]], [[N]]450; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]451; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]452; CHECK: ptr.check:453; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]]454; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]455; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]456; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]457; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]458; CHECK: exit:459; CHECK-NEXT: ret i4 3460;461entry:462 %src.end = getelementptr inbounds i8, ptr %src, i8 %N463 %cmp.src.start = icmp slt ptr %src, %lower464 %cmp.src.end = icmp sge ptr %src.end, %upper465 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end466 br i1 %or.precond.0, label %trap.bb, label %step.check467 468trap.bb:469 ret i4 2470 471step.check:472 %step.pos = icmp sge i8 %step, 0473 %step.slt.N = icmp slt i8 %step, %N474 %and.step = and i1 %step.pos, %step.slt.N475 br i1 %and.step, label %ptr.check, label %exit476 477ptr.check:478 %src.step = getelementptr inbounds i8, ptr %src, i8 %step479 %cmp.step.start = icmp slt ptr %src.step, %lower480 %cmp.step.end = icmp sge ptr %src.step, %upper481 %or.check = or i1 %cmp.step.start, %cmp.step.end482 br i1 %or.check, label %trap.bb, label %exit483 484exit:485 ret i4 3486}487 488define i4 @ptr_src_sge_end(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) {489; CHECK-LABEL: @ptr_src_sge_end(490; CHECK-NEXT: entry:491; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]492; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]493; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]494; CHECK-NEXT: [[CMP_OVERFLOW:%.*]] = icmp sgt ptr [[SRC]], [[SRC_END]]495; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]496; CHECK-NEXT: [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[CMP_OVERFLOW]]497; CHECK-NEXT: br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]498; CHECK: trap.bb:499; CHECK-NEXT: ret i4 2500; CHECK: step.check:501; CHECK-NEXT: [[STEP_POS:%.*]] = icmp sge i8 [[STEP:%.*]], 0502; CHECK-NEXT: [[STEP_SLT_N:%.*]] = icmp slt i8 [[STEP]], [[N]]503; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]504; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]505; CHECK: ptr.check:506; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]]507; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]508; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]509; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]510; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]511; CHECK: exit:512; CHECK-NEXT: ret i4 3513;514entry:515 %src.end = getelementptr inbounds i8, ptr %src, i8 %N516 %cmp.src.start = icmp slt ptr %src, %lower517 %cmp.src.end = icmp sge ptr %src.end, %upper518 %cmp.overflow = icmp sgt ptr %src, %src.end519 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end520 %or.precond.1 = or i1 %or.precond.0, %cmp.overflow521 br i1 %or.precond.1, label %trap.bb, label %step.check522 523trap.bb:524 ret i4 2525 526step.check:527 %step.pos = icmp sge i8 %step, 0528 %step.slt.N = icmp slt i8 %step, %N529 %and.step = and i1 %step.pos, %step.slt.N530 br i1 %and.step, label %ptr.check, label %exit531 532ptr.check:533 %src.step = getelementptr inbounds i8, ptr %src, i8 %step534 %cmp.step.start = icmp slt ptr %src.step, %lower535 %cmp.step.end = icmp sge ptr %src.step, %upper536 %or.check = or i1 %cmp.step.start, %cmp.step.end537 br i1 %or.check, label %trap.bb, label %exit538 539exit:540 ret i4 3541}542 543; N might be negative, meaning %src.end could be < %src! Cannot remove checks!544define i4 @ptr_N_unsigned_positive(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {545; CHECK-LABEL: @ptr_N_unsigned_positive(546; CHECK-NEXT: entry:547; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]548; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]549; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]550; CHECK-NEXT: [[N_NEG:%.*]] = icmp slt i16 [[N]], 0551; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]552; CHECK-NEXT: [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[N_NEG]]553; CHECK-NEXT: br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]554; CHECK: trap.bb:555; CHECK-NEXT: ret i4 2556; CHECK: step.check:557; CHECK-NEXT: [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0558; CHECK-NEXT: [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]559; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]560; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]561; CHECK: ptr.check:562; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]563; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]564; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]565; CHECK-NEXT: [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]566; CHECK-NEXT: br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]567; CHECK: exit:568; CHECK-NEXT: ret i4 3569;570entry:571 %src.end = getelementptr inbounds i8, ptr %src, i16 %N572 %cmp.src.start = icmp slt ptr %src, %lower573 %cmp.src.end = icmp sge ptr %src.end, %upper574 %N.neg = icmp slt i16 %N, 0575 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end576 %or.precond.1 = or i1 %or.precond.0, %N.neg577 br i1 %or.precond.1, label %trap.bb, label %step.check578 579trap.bb:580 ret i4 2581 582step.check:583 %step.pos = icmp sge i16 %step, 0584 %step.slt.N = icmp slt i16 %step, %N585 %and.step = and i1 %step.pos, %step.slt.N586 br i1 %and.step, label %ptr.check, label %exit587 588ptr.check:589 %src.step = getelementptr inbounds i8, ptr %src, i16 %step590 %cmp.step.start = icmp slt ptr %src.step, %lower591 %cmp.step.end = icmp sge ptr %src.step, %upper592 %or.check = or i1 %cmp.step.start, %cmp.step.end593 br i1 %or.check, label %trap.bb, label %exit594 595exit:596 ret i4 3597}598 599define i4 @ptr_N_signed_positive_assume(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {600; CHECK-LABEL: @ptr_N_signed_positive_assume(601; CHECK-NEXT: entry:602; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]603; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]604; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]605; CHECK-NEXT: [[N_NEG:%.*]] = icmp slt i16 [[N]], 0606; CHECK-NEXT: call void @llvm.assume(i1 [[N_NEG]])607; CHECK-NEXT: [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]608; CHECK-NEXT: br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]609; CHECK: trap.bb:610; CHECK-NEXT: ret i4 2611; CHECK: step.check:612; CHECK-NEXT: [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0613; CHECK-NEXT: [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]614; CHECK-NEXT: br i1 false, label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]615; CHECK: ptr.check:616; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]617; CHECK-NEXT: [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]618; CHECK-NEXT: [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]619; CHECK-NEXT: br i1 true, label [[TRAP_BB]], label [[EXIT]]620; CHECK: exit:621; CHECK-NEXT: ret i4 3622;623entry:624 %src.end = getelementptr inbounds i8, ptr %src, i16 %N625 %cmp.src.start = icmp slt ptr %src, %lower626 %cmp.src.end = icmp sge ptr %src.end, %upper627 %N.neg = icmp slt i16 %N, 0628 call void @llvm.assume(i1 %N.neg)629 %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end630 br i1 %or.precond.0, label %trap.bb, label %step.check631 632trap.bb:633 ret i4 2634 635step.check:636 %step.pos = icmp sge i16 %step, 0637 %step.slt.N = icmp slt i16 %step, %N638 %and.step = and i1 %step.pos, %step.slt.N639 br i1 %and.step, label %ptr.check, label %exit640 641ptr.check:642 %src.step = getelementptr inbounds i8, ptr %src, i16 %step643 %cmp.step.start = icmp slt ptr %src.step, %lower644 %cmp.step.end = icmp sge ptr %src.step, %upper645 %or.check = or i1 %cmp.step.start, %cmp.step.end646 br i1 %or.check, label %trap.bb, label %exit647 648exit:649 ret i4 3650}651