brintos

brintos / llvm-project-archived public Read only

0
0
Text · 31.6 KiB · df0cb40 Raw
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