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