785 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 @use(i1)5 6define void @test1(ptr %src, ptr noundef %lower, ptr noundef %upper, i8 %N) {7; CHECK-LABEL: @test1(8; CHECK-NEXT: entry:9; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]10; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]11; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]12; CHECK-NEXT: [[OR_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]13; CHECK-NEXT: br i1 [[OR_0]], label [[TRAP_BB:%.*]], label [[LOOP_HEADER:%.*]]14; CHECK: trap.bb:15; CHECK-NEXT: ret void16; CHECK: loop.header:17; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]18; CHECK-NEXT: [[EC:%.*]] = icmp uge i8 [[IV]], [[N]]19; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP_BODY:%.*]]20; CHECK: loop.body:21; CHECK-NEXT: [[SRC_IV:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[IV]]22; CHECK-NEXT: [[CMP_IV_END:%.*]] = icmp uge ptr [[SRC_IV]], [[UPPER]]23; CHECK-NEXT: [[OR_1:%.*]] = or i1 false, [[CMP_IV_END]]24; CHECK-NEXT: br i1 [[OR_1]], label [[TRAP_BB]], label [[LOOP_BODY_1:%.*]]25; CHECK: loop.body.1:26; CHECK-NEXT: [[PTR_SRC_IV:%.*]] = bitcast ptr [[SRC_IV]] to ptr27; CHECK-NEXT: store i32 0, ptr [[PTR_SRC_IV]], align 428; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[IV]], 129; CHECK-NEXT: [[SRC_IV_1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[ADD_1]]30; CHECK-NEXT: [[CMP_IV_1_END:%.*]] = icmp uge ptr [[SRC_IV_1]], [[UPPER]]31; CHECK-NEXT: [[OR_2:%.*]] = or i1 false, [[CMP_IV_1_END]]32; CHECK-NEXT: br i1 [[OR_2]], label [[TRAP_BB]], label [[LOOP_BODY_2:%.*]]33; CHECK: loop.body.2:34; CHECK-NEXT: [[PTR_SRC_IV_1:%.*]] = bitcast ptr [[SRC_IV_1]] to ptr35; CHECK-NEXT: store i32 0, ptr [[PTR_SRC_IV_1]], align 436; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[IV]], 237; CHECK-NEXT: [[SRC_IV_2:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[ADD_2]]38; CHECK-NEXT: [[CMP_IV_2_END:%.*]] = icmp uge ptr [[SRC_IV_2]], [[UPPER]]39; CHECK-NEXT: [[OR_3:%.*]] = or i1 false, [[CMP_IV_2_END]]40; CHECK-NEXT: br i1 [[OR_3]], label [[TRAP_BB]], label [[LOOP_LATCH]]41; CHECK: loop.latch:42; CHECK-NEXT: [[PTR_SRC_IV_2:%.*]] = bitcast ptr [[SRC_IV_2]] to ptr43; CHECK-NEXT: store i32 0, ptr [[PTR_SRC_IV_2]], align 444; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 145; CHECK-NEXT: br label [[LOOP_HEADER]]46; CHECK: exit:47; CHECK-NEXT: ret void48;49entry:50 %src.end = getelementptr inbounds i8, ptr %src, i8 %N51 %cmp.src.start = icmp ult ptr %src, %lower52 %cmp.src.end = icmp uge ptr %src.end, %upper53 %or.0 = or i1 %cmp.src.start, %cmp.src.end54 br i1 %or.0, label %trap.bb, label %loop.header55 56trap.bb:57 ret void58 59loop.header:60 %iv = phi i8 [ %iv.next, %loop.latch ], [ 0, %entry ]61 %ec = icmp uge i8 %iv, %N62 br i1 %ec, label %exit, label %loop.body63 64loop.body:65 %src.iv = getelementptr inbounds i8, ptr %src, i8 %iv66 %cmp.iv.start = icmp ult ptr %src.iv, %lower67 %cmp.iv.end = icmp uge ptr %src.iv, %upper68 %or.1 = or i1 %cmp.iv.start, %cmp.iv.end69 br i1 %or.1, label %trap.bb, label %loop.body.170 71loop.body.1:72 %ptr.src.iv = bitcast ptr %src.iv to ptr73 store i32 0, ptr %ptr.src.iv, align 474 %add.1 = add nuw nsw i8 %iv, 175 %src.iv.1 = getelementptr inbounds i8, ptr %src, i8 %add.176 %cmp.iv.1.start = icmp ult ptr %src.iv.1, %lower77 %cmp.iv.1.end = icmp uge ptr %src.iv.1, %upper78 %or.2 = or i1 %cmp.iv.1.start, %cmp.iv.1.end79 br i1 %or.2, label %trap.bb, label %loop.body.280 81loop.body.2:82 %ptr.src.iv.1 = bitcast ptr %src.iv.1 to ptr83 store i32 0, ptr %ptr.src.iv.1, align 484 %add.2 = add nuw nsw i8 %iv, 285 %src.iv.2 = getelementptr inbounds i8, ptr %src, i8 %add.286 %cmp.iv.2.start = icmp ult ptr %src.iv.2, %lower87 %cmp.iv.2.end = icmp uge ptr %src.iv.2, %upper88 %or.3 = or i1 %cmp.iv.2.start, %cmp.iv.2.end89 br i1 %or.3, label %trap.bb, label %loop.latch90 91loop.latch:92 %ptr.src.iv.2 = bitcast ptr %src.iv.2 to ptr93 store i32 0, ptr %ptr.src.iv.2, align 494 %iv.next = add nuw nsw i8 %iv, 195 br label %loop.header96 97exit:98 ret void99}100 101define void @test2(ptr %src, ptr %lower, ptr %upper, i8 %N) {102; CHECK-LABEL: @test2(103; CHECK-NEXT: entry:104; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]105; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]106; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]107; CHECK-NEXT: [[CMP_OVERFLOW:%.*]] = icmp ugt ptr [[SRC]], [[SRC_END]]108; CHECK-NEXT: [[OR_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]109; CHECK-NEXT: [[OR_11:%.*]] = or i1 [[OR_0]], [[CMP_OVERFLOW]]110; CHECK-NEXT: br i1 [[OR_11]], label [[TRAP_BB:%.*]], label [[LOOP_HEADER:%.*]]111; CHECK: trap.bb:112; CHECK-NEXT: ret void113; CHECK: loop.header:114; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 1, [[ENTRY:%.*]] ]115; CHECK-NEXT: [[NEXT:%.*]] = add nuw nsw i8 [[IV]], 2116; CHECK-NEXT: [[EC:%.*]] = icmp uge i8 [[NEXT]], [[N]]117; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP_BODY:%.*]]118; CHECK: loop.body:119; CHECK-NEXT: [[SRC_IV:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[IV]]120; CHECK-NEXT: [[CMP_IV_END:%.*]] = icmp uge ptr [[SRC_IV]], [[UPPER]]121; CHECK-NEXT: [[OR_1:%.*]] = or i1 false, [[CMP_IV_END]]122; CHECK-NEXT: br i1 [[OR_1]], label [[TRAP_BB]], label [[LOOP_BODY_1:%.*]]123; CHECK: loop.body.1:124; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[IV]], 1125; CHECK-NEXT: [[SRC_IV_1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[ADD_1]]126; CHECK-NEXT: [[CMP_IV_1_END:%.*]] = icmp uge ptr [[SRC_IV_1]], [[UPPER]]127; CHECK-NEXT: [[OR_2:%.*]] = or i1 false, [[CMP_IV_1_END]]128; CHECK-NEXT: br i1 [[OR_2]], label [[TRAP_BB]], label [[LOOP_BODY_2:%.*]]129; CHECK: loop.body.2:130; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[IV]], 2131; CHECK-NEXT: [[SRC_IV_2:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[ADD_2]]132; CHECK-NEXT: [[CMP_IV_2_END:%.*]] = icmp uge ptr [[SRC_IV_2]], [[UPPER]]133; CHECK-NEXT: [[OR_3:%.*]] = or i1 false, [[CMP_IV_2_END]]134; CHECK-NEXT: br i1 [[OR_3]], label [[TRAP_BB]], label [[LOOP_LATCH]]135; CHECK: loop.latch:136; CHECK-NEXT: [[PTR:%.*]] = bitcast ptr [[SRC_IV]] to ptr137; CHECK-NEXT: store i32 0, ptr [[PTR]], align 4138; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1139; CHECK-NEXT: br label [[LOOP_HEADER]]140; CHECK: exit:141; CHECK-NEXT: ret void142;143entry:144 %src.end = getelementptr inbounds i8, ptr %src, i8 %N145 %cmp.src.start = icmp ult ptr %src, %lower146 %cmp.src.end = icmp uge ptr %src.end, %upper147 %cmp.overflow = icmp ugt ptr %src, %src.end148 %or.0 = or i1 %cmp.src.start, %cmp.src.end149 %or.11 = or i1 %or.0, %cmp.overflow150 br i1 %or.11, label %trap.bb, label %loop.header151 152trap.bb:153 ret void154 155loop.header:156 %iv = phi i8 [ %iv.next, %loop.latch ], [ 1, %entry ]157 %next = add nuw nsw i8 %iv, 2158 %ec = icmp uge i8 %next, %N159 br i1 %ec, label %exit, label %loop.body160 161loop.body:162 %src.iv = getelementptr inbounds i8, ptr %src, i8 %iv163 %cmp.iv.start = icmp ult ptr %src.iv, %lower164 %cmp.iv.end = icmp uge ptr %src.iv, %upper165 %or.1 = or i1 %cmp.iv.start, %cmp.iv.end166 br i1 %or.1, label %trap.bb, label %loop.body.1167 168loop.body.1:169 %add.1 = add nuw nsw i8 %iv, 1170 %src.iv.1 = getelementptr inbounds i8, ptr %src, i8 %add.1171 %cmp.iv.1.start = icmp ult ptr %src.iv.1, %lower172 %cmp.iv.1.end = icmp uge ptr %src.iv.1, %upper173 %or.2 = or i1 %cmp.iv.1.start, %cmp.iv.1.end174 br i1 %or.2, label %trap.bb, label %loop.body.2175 176loop.body.2:177 %add.2 = add nuw nsw i8 %iv, 2178 %src.iv.2 = getelementptr inbounds i8, ptr %src, i8 %add.2179 %cmp.iv.2.start = icmp ult ptr %src.iv.2, %lower180 %cmp.iv.2.end = icmp uge ptr %src.iv.2, %upper181 %or.3 = or i1 %cmp.iv.2.start, %cmp.iv.2.end182 br i1 %or.3, label %trap.bb, label %loop.latch183 184loop.latch:185 %ptr = bitcast ptr %src.iv to ptr186 store i32 0, ptr %ptr, align 4187 %iv.next = add nuw nsw i8 %iv, 1188 br label %loop.header189 190exit:191 ret void192}193 194define void @test2_with_ne(ptr %src, ptr %lower, ptr %upper, i8 %N) {195; CHECK-LABEL: @test2_with_ne(196; CHECK-NEXT: entry:197; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]198; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]199; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]200; CHECK-NEXT: [[CMP_OVERFLOW:%.*]] = icmp ugt ptr [[SRC]], [[SRC_END]]201; CHECK-NEXT: [[OR_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]202; CHECK-NEXT: [[OR_11:%.*]] = or i1 [[OR_0]], [[CMP_OVERFLOW]]203; CHECK-NEXT: br i1 [[OR_11]], label [[TRAP_BB:%.*]], label [[LOOP_HEADER:%.*]]204; CHECK: trap.bb:205; CHECK-NEXT: ret void206; CHECK: loop.header:207; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 1, [[ENTRY:%.*]] ]208; CHECK-NEXT: [[NEXT:%.*]] = add nuw nsw i8 [[IV]], 1209; CHECK-NEXT: [[EC:%.*]] = icmp eq i8 [[NEXT]], [[N]]210; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP_BODY:%.*]]211; CHECK: loop.body:212; CHECK-NEXT: [[SRC_IV:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[IV]]213; CHECK-NEXT: [[CMP_IV_START:%.*]] = icmp ult ptr [[SRC_IV]], [[LOWER]]214; CHECK-NEXT: [[CMP_IV_END:%.*]] = icmp uge ptr [[SRC_IV]], [[UPPER]]215; CHECK-NEXT: br i1 [[CMP_IV_END]], label [[TRAP_BB]], label [[LOOP_BODY_1:%.*]]216; CHECK: loop.body.1:217; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i8 [[IV]], 1218; CHECK-NEXT: [[SRC_IV_1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[ADD_1]]219; CHECK-NEXT: [[CMP_IV_1_END:%.*]] = icmp uge ptr [[SRC_IV_1]], [[UPPER]]220; CHECK-NEXT: [[OR_2:%.*]] = or i1 false, [[CMP_IV_1_END]]221; CHECK-NEXT: br i1 [[OR_2]], label [[TRAP_BB]], label [[LOOP_BODY_2:%.*]]222; CHECK: loop.body.2:223; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[IV]], 2224; CHECK-NEXT: [[SRC_IV_2:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[ADD_2]]225; CHECK-NEXT: [[CMP_IV_2_END:%.*]] = icmp uge ptr [[SRC_IV_2]], [[UPPER]]226; CHECK-NEXT: [[OR_3:%.*]] = or i1 false, [[CMP_IV_2_END]]227; CHECK-NEXT: br i1 [[OR_3]], label [[TRAP_BB]], label [[LOOP_LATCH]]228; CHECK: loop.latch:229; CHECK-NEXT: [[PTR:%.*]] = bitcast ptr [[SRC_IV]] to ptr230; CHECK-NEXT: store i32 0, ptr [[PTR]], align 4231; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1232; CHECK-NEXT: br label [[LOOP_HEADER]]233; CHECK: exit:234; CHECK-NEXT: ret void235;236entry:237 %src.end = getelementptr inbounds i8, ptr %src, i8 %N238 %cmp.src.start = icmp ult ptr %src, %lower239 %cmp.src.end = icmp uge ptr %src.end, %upper240 %cmp.overflow = icmp ugt ptr %src, %src.end241 %or.0 = or i1 %cmp.src.start, %cmp.src.end242 %or.11 = or i1 %or.0, %cmp.overflow243 br i1 %or.11, label %trap.bb, label %loop.header244 245trap.bb:246 ret void247 248loop.header:249 %iv = phi i8 [ %iv.next, %loop.latch ], [ 1, %entry ]250 %next = add nuw nsw i8 %iv, 1251 %ec = icmp eq i8 %next, %N252 br i1 %ec, label %exit, label %loop.body253 254loop.body:255 %src.iv = getelementptr inbounds i8, ptr %src, i8 %iv256 %cmp.iv.start = icmp ult ptr %src.iv, %lower257 %cmp.iv.end = icmp uge ptr %src.iv, %upper258 %or.1 = or i1 %cmp.iv.start, %cmp.iv.end259 br i1 %or.1, label %trap.bb, label %loop.body.1260 261loop.body.1:262 %add.1 = add nuw nsw i8 %iv, 1263 %src.iv.1 = getelementptr inbounds i8, ptr %src, i8 %add.1264 %cmp.iv.1.start = icmp ult ptr %src.iv.1, %lower265 %cmp.iv.1.end = icmp uge ptr %src.iv.1, %upper266 %or.2 = or i1 %cmp.iv.1.start, %cmp.iv.1.end267 br i1 %or.2, label %trap.bb, label %loop.body.2268 269loop.body.2:270 %add.2 = add nuw nsw i8 %iv, 2271 %src.iv.2 = getelementptr inbounds i8, ptr %src, i8 %add.2272 %cmp.iv.2.start = icmp ult ptr %src.iv.2, %lower273 %cmp.iv.2.end = icmp uge ptr %src.iv.2, %upper274 %or.3 = or i1 %cmp.iv.2.start, %cmp.iv.2.end275 br i1 %or.3, label %trap.bb, label %loop.latch276 277loop.latch:278 %ptr = bitcast ptr %src.iv to ptr279 store i32 0, ptr %ptr, align 4280 %iv.next = add nuw nsw i8 %iv, 1281 br label %loop.header282 283exit:284 ret void285}286 287define void @test3(ptr %src, ptr %lower, ptr %upper, i8 %N) {288; CHECK-LABEL: @test3(289; CHECK-NEXT: entry:290; CHECK-NEXT: [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]291; CHECK-NEXT: [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]292; CHECK-NEXT: [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]293; CHECK-NEXT: [[CMP_OVERFLOW:%.*]] = icmp ugt ptr [[SRC]], [[SRC_END]]294; CHECK-NEXT: [[OR_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]295; CHECK-NEXT: [[OR_11:%.*]] = or i1 [[OR_0]], [[CMP_OVERFLOW]]296; CHECK-NEXT: br i1 [[OR_11]], label [[TRAP_BB:%.*]], label [[LOOP_HEADER:%.*]]297; CHECK: trap.bb:298; CHECK-NEXT: ret void299; CHECK: loop.header:300; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 1, [[ENTRY:%.*]] ]301; CHECK-NEXT: [[NEXT:%.*]] = or i8 [[IV]], 1302; CHECK-NEXT: [[EC:%.*]] = icmp ult i8 [[NEXT]], [[N]]303; CHECK-NEXT: br i1 [[EC]], label [[LOOP_BODY:%.*]], label [[EXIT:%.*]]304; CHECK: loop.body:305; CHECK-NEXT: [[SRC_IV:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[IV]]306; CHECK-NEXT: [[CMP_IV_START:%.*]] = icmp ult ptr [[SRC_IV]], [[LOWER]]307; CHECK-NEXT: [[CMP_IV_END:%.*]] = icmp uge ptr [[SRC_IV]], [[UPPER]]308; CHECK-NEXT: br i1 [[CMP_IV_END]], label [[TRAP_BB]], label [[LOOP_BODY_1:%.*]]309; CHECK: loop.body.1:310; CHECK-NEXT: [[SRC_IV_1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[NEXT]]311; CHECK-NEXT: [[CMP_IV_1_END:%.*]] = icmp uge ptr [[SRC_IV_1]], [[UPPER]]312; CHECK-NEXT: [[OR_2:%.*]] = or i1 false, [[CMP_IV_1_END]]313; CHECK-NEXT: br i1 [[OR_2]], label [[TRAP_BB]], label [[LOOP_BODY_2:%.*]]314; CHECK: loop.body.2:315; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i8 [[IV]], 2316; CHECK-NEXT: [[SRC_IV_2:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[ADD_2]]317; CHECK-NEXT: [[CMP_IV_2_END:%.*]] = icmp uge ptr [[SRC_IV_2]], [[UPPER]]318; CHECK-NEXT: [[OR_3:%.*]] = or i1 false, [[CMP_IV_2_END]]319; CHECK-NEXT: br i1 [[OR_3]], label [[TRAP_BB]], label [[LOOP_LATCH]]320; CHECK: loop.latch:321; CHECK-NEXT: [[PTR:%.*]] = bitcast ptr [[SRC_IV]] to ptr322; CHECK-NEXT: store i32 0, ptr [[PTR]], align 4323; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i8 [[IV]], 1324; CHECK-NEXT: br label [[LOOP_HEADER]]325; CHECK: exit:326; CHECK-NEXT: ret void327;328entry:329 %src.end = getelementptr inbounds i8, ptr %src, i8 %N330 %cmp.src.start = icmp ult ptr %src, %lower331 %cmp.src.end = icmp uge ptr %src.end, %upper332 %cmp.overflow = icmp ugt ptr %src, %src.end333 %or.0 = or i1 %cmp.src.start, %cmp.src.end334 %or.11 = or i1 %or.0, %cmp.overflow335 br i1 %or.11, label %trap.bb, label %loop.header336 337trap.bb:338 ret void339 340loop.header:341 %iv = phi i8 [ %iv.next, %loop.latch ], [ 1, %entry ]342 %next = or i8 %iv, 1343 %ec = icmp ult i8 %next, %N344 br i1 %ec, label %loop.body, label %exit345 346loop.body:347 %src.iv = getelementptr inbounds i8, ptr %src, i8 %iv348 %cmp.iv.start = icmp ult ptr %src.iv, %lower349 %cmp.iv.end = icmp uge ptr %src.iv, %upper350 %or.1 = or i1 %cmp.iv.start, %cmp.iv.end351 br i1 %or.1, label %trap.bb, label %loop.body.1352 353loop.body.1:354 %src.iv.1 = getelementptr inbounds i8, ptr %src, i8 %next355 %cmp.iv.1.start = icmp ult ptr %src.iv.1, %lower356 %cmp.iv.1.end = icmp uge ptr %src.iv.1, %upper357 %or.2 = or i1 %cmp.iv.1.start, %cmp.iv.1.end358 br i1 %or.2, label %trap.bb, label %loop.body.2359 360loop.body.2:361 %add.2 = add nuw nsw i8 %iv, 2362 %src.iv.2 = getelementptr inbounds i8, ptr %src, i8 %add.2363 %cmp.iv.2.start = icmp ult ptr %src.iv.2, %lower364 %cmp.iv.2.end = icmp uge ptr %src.iv.2, %upper365 %or.3 = or i1 %cmp.iv.2.start, %cmp.iv.2.end366 br i1 %or.3, label %trap.bb, label %loop.latch367 368loop.latch:369 %ptr = bitcast ptr %src.iv to ptr370 store i32 0, ptr %ptr, align 4371 %iv.next = add nuw nsw i8 %iv, 1372 br label %loop.header373 374exit:375 ret void376}377 378; Cannot remove checks, because %n may be negative.379define void @ne_check_in_loop_no_zext_n_may_be_negative(ptr %ptr, ptr %lower, ptr %upper, i16 %n) {380; CHECK-LABEL: @ne_check_in_loop_no_zext_n_may_be_negative(381; CHECK-NEXT: entry:382; CHECK-NEXT: [[CMP_PTR_LOWER:%.*]] = icmp ult ptr [[PTR:%.*]], [[LOWER:%.*]]383; CHECK-NEXT: br i1 [[CMP_PTR_LOWER]], label [[TRAP:%.*]], label [[PRE:%.*]]384; CHECK: pre:385; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i16 [[N:%.*]]386; CHECK-NEXT: [[CMP_PTR_N_UPPER:%.*]] = icmp ult ptr [[ADD_PTR]], [[UPPER:%.*]]387; CHECK-NEXT: br i1 [[CMP_PTR_N_UPPER]], label [[FOR_COND_PREHEADER:%.*]], label [[TRAP]]388; CHECK: for.cond.preheader:389; CHECK-NEXT: br label [[FOR_HEADER:%.*]]390; CHECK: trap:391; CHECK-NEXT: ret void392; CHECK: for.header:393; CHECK-NEXT: [[IV:%.*]] = phi i16 [ 0, [[FOR_COND_PREHEADER]] ], [ [[IV_NEXT:%.*]], [[FOR_LATCH:%.*]] ]394; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i16 [[IV]], [[N]]395; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]396; CHECK: for.body:397; CHECK-NEXT: [[GEP_IV:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i16 [[IV]]398; CHECK-NEXT: [[CMP_IV_UPPER:%.*]] = icmp ule ptr [[UPPER]], [[GEP_IV]]399; CHECK-NEXT: [[OR:%.*]] = or i1 false, [[CMP_IV_UPPER]]400; CHECK-NEXT: br i1 [[OR]], label [[TRAP]], label [[FOR_BODY_1:%.*]]401; CHECK: for.body.1:402; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[IV]], 1403; CHECK-NEXT: [[GEP_IV_1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i16 [[ADD]]404; CHECK-NEXT: [[CMP_IV_1_UPPER:%.*]] = icmp ule ptr [[UPPER]], [[GEP_IV_1]]405; CHECK-NEXT: [[OR_1:%.*]] = or i1 false, [[CMP_IV_1_UPPER]]406; CHECK-NEXT: br i1 [[OR_1]], label [[TRAP]], label [[FOR_LATCH]]407; CHECK: for.latch:408; CHECK-NEXT: store i8 0, ptr [[GEP_IV]], align 4409; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1410; CHECK-NEXT: br label [[FOR_HEADER]]411; CHECK: for.end:412; CHECK-NEXT: ret void413;414entry:415 %cmp.ptr.lower = icmp ult ptr %ptr, %lower416 br i1 %cmp.ptr.lower, label %trap, label %pre417 418pre:419 %add.ptr = getelementptr inbounds i8, ptr %ptr, i16 %n420 %cmp.ptr.n.upper = icmp ult ptr %add.ptr, %upper421 br i1 %cmp.ptr.n.upper, label %for.cond.preheader, label %trap422 423for.cond.preheader:424 br label %for.header425 426trap:427 ret void428 429for.header:430 %iv = phi i16 [ 0, %for.cond.preheader ], [ %iv.next, %for.latch ]431 %exitcond = icmp ne i16 %iv, %n432 br i1 %exitcond, label %for.body, label %for.end433 434for.body:435 %gep.iv = getelementptr inbounds i8, ptr %ptr, i16 %iv436 %cmp.iv.lower = icmp ugt ptr %lower, %gep.iv437 %cmp.iv.upper = icmp ule ptr %upper, %gep.iv438 %or = or i1 %cmp.iv.lower, %cmp.iv.upper439 br i1 %or, label %trap, label %for.body.1440 441for.body.1:442 %add = add nuw nsw i16 %iv, 1443 %gep.iv.1 = getelementptr inbounds i8, ptr %ptr, i16 %add444 %cmp.iv.1.lower = icmp ugt ptr %lower, %gep.iv.1445 %cmp.iv.1.upper = icmp ule ptr %upper, %gep.iv.1446 %or.1 = or i1 %cmp.iv.1.lower, %cmp.iv.1.upper447 br i1 %or.1, label %trap, label %for.latch448 449for.latch:450 store i8 0, ptr %gep.iv, align 4451 %iv.next = add nuw nsw i16 %iv, 1452 br label %for.header453 454for.end:455 ret void456}457 458; Should be able to remove the checks in the loop, because %n is signed positive.459define void @ne_check_in_loop_no_zext_n_positive_check(ptr %ptr, ptr %lower, ptr %upper, i16 %n) {460; CHECK-LABEL: @ne_check_in_loop_no_zext_n_positive_check(461; CHECK-NEXT: entry:462; CHECK-NEXT: [[N_SIGNED_POSITIVE:%.*]] = icmp slt i16 [[N:%.*]], 0463; CHECK-NEXT: [[CMP_PTR_LOWER:%.*]] = icmp ult ptr [[PTR:%.*]], [[LOWER:%.*]]464; CHECK-NEXT: [[OR_T:%.*]] = or i1 [[N_SIGNED_POSITIVE]], [[CMP_PTR_LOWER]]465; CHECK-NEXT: br i1 [[OR_T]], label [[TRAP:%.*]], label [[PRE:%.*]]466; CHECK: pre:467; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i16 [[N]]468; CHECK-NEXT: [[CMP_PTR_N_UPPER:%.*]] = icmp ult ptr [[ADD_PTR]], [[UPPER:%.*]]469; CHECK-NEXT: br i1 [[CMP_PTR_N_UPPER]], label [[FOR_COND_PREHEADER:%.*]], label [[TRAP]]470; CHECK: for.cond.preheader:471; CHECK-NEXT: br label [[FOR_HEADER:%.*]]472; CHECK: trap:473; CHECK-NEXT: ret void474; CHECK: for.header:475; CHECK-NEXT: [[IV:%.*]] = phi i16 [ 0, [[FOR_COND_PREHEADER]] ], [ [[IV_NEXT:%.*]], [[FOR_LATCH:%.*]] ]476; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i16 [[IV]], [[N]]477; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]478; CHECK: for.body:479; CHECK-NEXT: [[GEP_IV:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i16 [[IV]]480; CHECK-NEXT: [[OR:%.*]] = or i1 false, false481; CHECK-NEXT: br i1 [[OR]], label [[TRAP]], label [[FOR_BODY_1:%.*]]482; CHECK: for.body.1:483; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[IV]], 1484; CHECK-NEXT: [[GEP_IV_1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i16 [[ADD]]485; CHECK-NEXT: [[OR_1:%.*]] = or i1 false, false486; CHECK-NEXT: br i1 [[OR_1]], label [[TRAP]], label [[FOR_LATCH]]487; CHECK: for.latch:488; CHECK-NEXT: store i8 0, ptr [[GEP_IV]], align 4489; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1490; CHECK-NEXT: br label [[FOR_HEADER]]491; CHECK: for.end:492; CHECK-NEXT: ret void493;494entry:495 %n.signed.positive = icmp slt i16 %n, 0496 %cmp.ptr.lower = icmp ult ptr %ptr, %lower497 %or.t = or i1 %n.signed.positive, %cmp.ptr.lower498 br i1 %or.t, label %trap, label %pre499 500pre:501 %add.ptr = getelementptr inbounds i8, ptr %ptr, i16 %n502 %cmp.ptr.n.upper = icmp ult ptr %add.ptr, %upper503 br i1 %cmp.ptr.n.upper, label %for.cond.preheader, label %trap504 505for.cond.preheader:506 br label %for.header507 508trap:509 ret void510 511for.header:512 %iv = phi i16 [ 0, %for.cond.preheader ], [ %iv.next, %for.latch ]513 %exitcond = icmp ne i16 %iv, %n514 br i1 %exitcond, label %for.body, label %for.end515 516for.body:517 %gep.iv = getelementptr inbounds i8, ptr %ptr, i16 %iv518 %cmp.iv.lower = icmp ugt ptr %lower, %gep.iv519 %cmp.iv.upper = icmp ule ptr %upper, %gep.iv520 %or = or i1 %cmp.iv.lower, %cmp.iv.upper521 br i1 %or, label %trap, label %for.body.1522 523for.body.1:524 %add = add nuw nsw i16 %iv, 1525 %gep.iv.1 = getelementptr inbounds i8, ptr %ptr, i16 %add526 %cmp.iv.1.lower = icmp ugt ptr %lower, %gep.iv.1527 %cmp.iv.1.upper = icmp ule ptr %upper, %gep.iv.1528 %or.1 = or i1 %cmp.iv.1.lower, %cmp.iv.1.upper529 br i1 %or.1, label %trap, label %for.latch530 531for.latch:532 store i8 0, ptr %gep.iv, align 4533 %iv.next = add nuw nsw i16 %iv, 1534 br label %for.header535 536for.end:537 ret void538}539 540; Make sure icmp ne of the induction variable in the loop body can be handled541; and is treated as ule.542define void @ne_check_in_loop_with_zext(ptr %ptr, ptr %lower, ptr %upper, i8 %n) {543; CHECK-LABEL: @ne_check_in_loop_with_zext(544; CHECK-NEXT: entry:545; CHECK-NEXT: [[CMP_PTR_LOWER:%.*]] = icmp ult ptr [[PTR:%.*]], [[LOWER:%.*]]546; CHECK-NEXT: br i1 [[CMP_PTR_LOWER]], label [[TRAP:%.*]], label [[PRE:%.*]]547; CHECK: pre:548; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[N:%.*]] to i16549; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i16 [[IDX_EXT]]550; CHECK-NEXT: [[CMP_PTR_N_UPPER:%.*]] = icmp ult ptr [[ADD_PTR]], [[UPPER:%.*]]551; CHECK-NEXT: br i1 [[CMP_PTR_N_UPPER]], label [[FOR_COND_PREHEADER:%.*]], label [[TRAP]]552; CHECK: for.cond.preheader:553; CHECK-NEXT: br label [[FOR_HEADER:%.*]]554; CHECK: trap:555; CHECK-NEXT: ret void556; CHECK: for.header:557; CHECK-NEXT: [[IV:%.*]] = phi i16 [ 0, [[FOR_COND_PREHEADER]] ], [ [[IV_NEXT:%.*]], [[FOR_LATCH:%.*]] ]558; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i16 [[IV]], [[IDX_EXT]]559; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]560; CHECK: for.body:561; CHECK-NEXT: [[GEP_IV:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i16 [[IV]]562; CHECK-NEXT: [[OR:%.*]] = or i1 false, false563; CHECK-NEXT: br i1 [[OR]], label [[TRAP]], label [[FOR_BODY_1:%.*]]564; CHECK: for.body.1:565; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[IV]], 1566; CHECK-NEXT: [[GEP_IV_1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i16 [[ADD]]567; CHECK-NEXT: [[OR_1:%.*]] = or i1 false, false568; CHECK-NEXT: br i1 [[OR_1]], label [[TRAP]], label [[FOR_LATCH]]569; CHECK: for.latch:570; CHECK-NEXT: store i8 0, ptr [[GEP_IV]], align 4571; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1572; CHECK-NEXT: br label [[FOR_HEADER]]573; CHECK: for.end:574; CHECK-NEXT: ret void575;576entry:577 %cmp.ptr.lower = icmp ult ptr %ptr, %lower578 br i1 %cmp.ptr.lower, label %trap, label %pre579 580pre:581 %idx.ext = zext i8 %n to i16582 %add.ptr = getelementptr inbounds i8, ptr %ptr, i16 %idx.ext583 %cmp.ptr.n.upper = icmp ult ptr %add.ptr, %upper584 br i1 %cmp.ptr.n.upper, label %for.cond.preheader, label %trap585 586for.cond.preheader:587 br label %for.header588 589trap:590 ret void591 592for.header:593 %iv = phi i16 [ 0, %for.cond.preheader ], [ %iv.next, %for.latch ]594 %exitcond = icmp ne i16 %iv, %idx.ext595 br i1 %exitcond, label %for.body, label %for.end596 597for.body:598 %gep.iv = getelementptr inbounds i8, ptr %ptr, i16 %iv599 %cmp.iv.lower = icmp ugt ptr %lower, %gep.iv600 %cmp.iv.upper = icmp ule ptr %upper, %gep.iv601 %or = or i1 %cmp.iv.lower, %cmp.iv.upper602 br i1 %or, label %trap, label %for.body.1603 604for.body.1:605 %add = add nuw nsw i16 %iv, 1606 %gep.iv.1 = getelementptr inbounds i8, ptr %ptr, i16 %add607 %cmp.iv.1.lower = icmp ugt ptr %lower, %gep.iv.1608 %cmp.iv.1.upper = icmp ule ptr %upper, %gep.iv.1609 %or.1 = or i1 %cmp.iv.1.lower, %cmp.iv.1.upper610 br i1 %or.1, label %trap, label %for.latch611 612for.latch:613 store i8 0, ptr %gep.iv, align 4614 %iv.next = add nuw nsw i16 %iv, 1615 br label %for.header616 617for.end:618 ret void619}620 621define void @test_ptr_need_one_upper_check(ptr readonly %src, ptr %dst, i32 %n) {622; CHECK-LABEL: @test_ptr_need_one_upper_check(623; CHECK-NEXT: entry:624; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]625; CHECK: loop.header:626; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[LOOP_LATCH_2:%.*]] ]627; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[I_0]], [[N:%.*]]628; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_CHECK_1:%.*]], label [[EXIT:%.*]]629; CHECK: loop.check.1:630; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[N]] to i64631; CHECK-NEXT: [[SRC_UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[TMP0]]632; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[I_0]], 2633; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[ADD]] to i64634; CHECK-NEXT: [[SRC_IDX:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[IDXPROM]]635; CHECK-NEXT: [[CMP_SRC_IDX_UPPER:%.*]] = icmp ult ptr [[SRC_IDX]], [[SRC_UPPER]]636; CHECK-NEXT: call void @use(i1 [[CMP_SRC_IDX_UPPER]])637; CHECK-NEXT: br i1 [[CMP_SRC_IDX_UPPER]], label [[LOOP_LATCH:%.*]], label [[EXIT]]638; CHECK: loop.latch:639; CHECK-NEXT: [[DST_UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST:%.*]], i64 [[TMP0]]640; CHECK-NEXT: [[DST_IDX:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IDXPROM]]641; CHECK-NEXT: call void @use(i1 true)642; CHECK-NEXT: br i1 true, label [[LOOP_LATCH_2]], label [[EXIT]]643; CHECK: loop.latch.2:644; CHECK-NEXT: br label [[LOOP_HEADER]]645; CHECK: exit:646; CHECK-NEXT: ret void647;648entry:649 br label %loop.header650 651loop.header:652 %i.0 = phi i32 [ 0, %entry ], [ %add, %loop.latch.2 ]653 %cmp = icmp ult i32 %i.0, %n654 br i1 %cmp, label %loop.check.1, label %exit655 656loop.check.1:657 %0 = zext i32 %n to i64658 %src.upper = getelementptr inbounds i32, ptr %src, i64 %0659 %add = add nuw nsw i32 %i.0, 2660 %idxprom = zext i32 %add to i64661 %src.idx = getelementptr inbounds i32, ptr %src, i64 %idxprom662 %cmp.src.idx.upper = icmp ult ptr %src.idx, %src.upper663 call void @use(i1 %cmp.src.idx.upper)664 br i1 %cmp.src.idx.upper, label %loop.latch, label %exit665 666loop.latch:667 %dst.upper = getelementptr inbounds i32, ptr %dst, i64 %0668 %dst.idx = getelementptr inbounds i32, ptr %dst, i64 %idxprom669 %cmp.dst.idx.upper = icmp ult ptr %dst.idx, %dst.upper670 call void @use(i1 %cmp.dst.idx.upper)671 br i1 %cmp.dst.idx.upper, label %loop.latch.2, label %exit672 673loop.latch.2:674 br label %loop.header675 676exit:677 ret void678}679 680; Same as test_ptr_need_one_upper_check, but without inbounds GEP.681define void @test_ptr_need_one_upper_check_no_inbounds(ptr readonly %src, ptr %dst, i32 %n) {682; CHECK-LABEL: @test_ptr_need_one_upper_check_no_inbounds(683; CHECK-NEXT: entry:684; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]685; CHECK: loop.header:686; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[LOOP_LATCH_2:%.*]] ]687; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[I_0]], [[N:%.*]]688; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_CHECK_1:%.*]], label [[EXIT:%.*]]689; CHECK: loop.check.1:690; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[N]] to i64691; CHECK-NEXT: [[SRC_UPPER:%.*]] = getelementptr i32, ptr [[SRC:%.*]], i64 [[TMP0]]692; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[I_0]], 2693; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[ADD]] to i64694; CHECK-NEXT: [[SRC_IDX:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[IDXPROM]]695; CHECK-NEXT: [[CMP_SRC_IDX_UPPER:%.*]] = icmp ult ptr [[SRC_IDX]], [[SRC_UPPER]]696; CHECK-NEXT: call void @use(i1 [[CMP_SRC_IDX_UPPER]])697; CHECK-NEXT: br i1 [[CMP_SRC_IDX_UPPER]], label [[LOOP_LATCH:%.*]], label [[EXIT]]698; CHECK: loop.latch:699; CHECK-NEXT: [[DST_UPPER:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 [[TMP0]]700; CHECK-NEXT: [[DST_IDX:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IDXPROM]]701; CHECK-NEXT: [[CMP_DST_IDX_UPPER:%.*]] = icmp ult ptr [[DST_IDX]], [[DST_UPPER]]702; CHECK-NEXT: call void @use(i1 [[CMP_DST_IDX_UPPER]])703; CHECK-NEXT: br i1 [[CMP_DST_IDX_UPPER]], label [[LOOP_LATCH_2]], label [[EXIT]]704; CHECK: loop.latch.2:705; CHECK-NEXT: br label [[LOOP_HEADER]]706; CHECK: exit:707; CHECK-NEXT: ret void708;709entry:710 br label %loop.header711 712loop.header:713 %i.0 = phi i32 [ 0, %entry ], [ %add, %loop.latch.2 ]714 %cmp = icmp ult i32 %i.0, %n715 br i1 %cmp, label %loop.check.1, label %exit716 717loop.check.1:718 %0 = zext i32 %n to i64719 %src.upper = getelementptr i32, ptr %src, i64 %0720 %add = add nuw nsw i32 %i.0, 2721 %idxprom = zext i32 %add to i64722 %src.idx = getelementptr inbounds i32, ptr %src, i64 %idxprom723 %cmp.src.idx.upper = icmp ult ptr %src.idx, %src.upper724 call void @use(i1 %cmp.src.idx.upper)725 br i1 %cmp.src.idx.upper, label %loop.latch, label %exit726 727loop.latch:728 %dst.upper = getelementptr i32, ptr %dst, i64 %0729 %dst.idx = getelementptr inbounds i32, ptr %dst, i64 %idxprom730 %cmp.dst.idx.upper = icmp ult ptr %dst.idx, %dst.upper731 call void @use(i1 %cmp.dst.idx.upper)732 br i1 %cmp.dst.idx.upper, label %loop.latch.2, label %exit733 734loop.latch.2:735 br label %loop.header736 737exit:738 ret void739}740 741; Test case that exposed a crash in the earlier NewVariables handling code.742define void @test_only_some_new_variables_may_be_0(ptr %A, ptr %start) {743; CHECK-LABEL: @test_only_some_new_variables_may_be_0(744; CHECK-NEXT: entry:745; CHECK-NEXT: [[A_10:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 10746; CHECK-NEXT: br label [[HEADER:%.*]]747; CHECK: header:748; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]749; CHECK-NEXT: [[A_IV:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]750; CHECK-NEXT: [[C_1:%.*]] = icmp ult ptr [[A_IV]], [[A_10]]751; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[A_IV]], [[START:%.*]]752; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_1]], [[C_2]]753; CHECK-NEXT: br i1 [[AND]], label [[LATCH]], label [[EXIT:%.*]]754; CHECK: latch:755; CHECK-NEXT: call void @clobber()756; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], -1757; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp eq i64 [[IV]], 0758; CHECK-NEXT: br i1 [[CMP_NOT_I]], label [[HEADER]], label [[EXIT]]759; CHECK: exit:760; CHECK-NEXT: ret void761;762entry:763 %A.10 = getelementptr inbounds i32, ptr %A, i64 10764 br label %header765 766header:767 %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]768 %A.iv = getelementptr i32, ptr %A, i64 %iv769 %c.1 = icmp ult ptr %A.iv, %A.10770 %c.2 = icmp uge ptr %A.iv, %start771 %and = and i1 %c.1, %c.2772 br i1 %and, label %latch, label %exit773 774latch:775 call void @clobber()776 %iv.next = add nsw i64 %iv, -1777 %cmp.not.i = icmp eq i64 %iv, 0778 br i1 %cmp.not.i, label %header, label %exit779 780exit:781 ret void782}783 784declare void @clobber()785