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