brintos

brintos / llvm-project-archived public Read only

0
0
Text · 25.5 KiB · 68613fe Raw
499 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 32; RUN: opt -verify-loop-info -irce-print-changed-loops -passes=irce -S < %s 2>&1 | FileCheck %s3; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,irce' -S < %s 2>&1 | FileCheck %s4 5; CHECK-LABEL: irce: in function test_01: constrained Loop at depth 1 containing:6; CHECK-LABEL: irce: in function test_02: constrained Loop at depth 1 containing:7; CHECK-LABEL: irce: in function test_03: constrained Loop at depth 1 containing:8; CHECK-LABEL: irce: in function test_04: constrained Loop at depth 1 containing:9; CHECK-LABEL: irce: in function test_05: constrained Loop at depth 1 containing:10 11; This test used to demonstrate a miscompile: the outer loop's IV iterates in12; range of [2, 400) and the range check is done against value 331. Due to a bug13; in range intersection IRCE manages to eliminate the range check without14; inserting a postloop, which is incorrect. We treat the range of this test as15; an unsigned range and are able to intersect ranges correctly and insert a16; postloop.17 18define void @test_01() {19; CHECK-LABEL: define void @test_01() {20; CHECK-NEXT:  entry:21; CHECK-NEXT:    br i1 true, label [[LOOP_HEADER_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]22; CHECK:       loop_header.preheader:23; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]24; CHECK:       loop_header:25; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 2, [[LOOP_HEADER_PREHEADER]] ]26; CHECK-NEXT:    [[IV_PREV:%.*]] = phi i32 [ [[IV]], [[LOOP_LATCH]] ], [ 1, [[LOOP_HEADER_PREHEADER]] ]27; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[IV_PREV]], -128; CHECK-NEXT:    br i1 true, label [[LOOP_HEADER_SPLIT_US:%.*]], label [[EXIT_LOOPEXIT1:%.*]]29; CHECK:       loop_header.split.us:30; CHECK-NEXT:    br label [[INNER_LOOP:%.*]]31; CHECK:       inner_loop:32; CHECK-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 1, [[LOOP_HEADER_SPLIT_US]] ], [ [[INNER_IV_NEXT:%.*]], [[INNER_LOOP]] ]33; CHECK-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 134; CHECK-NEXT:    [[INNER_COND:%.*]] = icmp ult i32 [[INNER_IV_NEXT]], 3135; CHECK-NEXT:    br i1 [[INNER_COND]], label [[INNER_LOOP]], label [[RANGE_CHECK_BLOCK:%.*]]36; CHECK:       exit.loopexit:37; CHECK-NEXT:    br label [[EXIT:%.*]]38; CHECK:       exit.loopexit1:39; CHECK-NEXT:    br label [[EXIT]]40; CHECK:       exit:41; CHECK-NEXT:    ret void42; CHECK:       range_check_block:43; CHECK-NEXT:    [[RANGE_CHECK:%.*]] = icmp slt i32 [[IV]], 33144; CHECK-NEXT:    br i1 true, label [[LOOP_LATCH]], label [[DEOPT_LOOPEXIT2:%.*]]45; CHECK:       loop_latch:46; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 147; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 40048; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[IV_NEXT]], 33149; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_HEADER]], label [[MAIN_EXIT_SELECTOR:%.*]]50; CHECK:       main.exit.selector:51; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[LOOP_LATCH]] ]52; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP_LATCH]] ]53; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[IV_NEXT_LCSSA]], 40054; CHECK-NEXT:    br i1 [[TMP1]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT]]55; CHECK:       main.pseudo.exit:56; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ 2, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]57; CHECK-NEXT:    [[IV_PREV_COPY:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]58; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 2, [[ENTRY]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]59; CHECK-NEXT:    br label [[POSTLOOP:%.*]]60; CHECK:       deopt.loopexit:61; CHECK-NEXT:    br label [[DEOPT:%.*]]62; CHECK:       deopt.loopexit2:63; CHECK-NEXT:    br label [[DEOPT]]64; CHECK:       deopt:65; CHECK-NEXT:    ret void66; CHECK:       postloop:67; CHECK-NEXT:    br label [[LOOP_HEADER_POSTLOOP:%.*]]68; CHECK:       loop_header.postloop:69; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i32 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[LOOP_LATCH_POSTLOOP:%.*]] ]70; CHECK-NEXT:    [[IV_PREV_POSTLOOP:%.*]] = phi i32 [ [[IV_PREV_COPY]], [[POSTLOOP]] ], [ [[IV_POSTLOOP]], [[LOOP_LATCH_POSTLOOP]] ]71; CHECK-NEXT:    [[TMP2_POSTLOOP:%.*]] = icmp sgt i32 [[IV_PREV_POSTLOOP]], -172; CHECK-NEXT:    br i1 [[TMP2_POSTLOOP]], label [[LOOP_HEADER_SPLIT_US_POSTLOOP:%.*]], label [[EXIT_LOOPEXIT:%.*]]73; CHECK:       loop_header.split.us.postloop:74; CHECK-NEXT:    br label [[INNER_LOOP_POSTLOOP:%.*]]75; CHECK:       inner_loop.postloop:76; CHECK-NEXT:    [[INNER_IV_POSTLOOP:%.*]] = phi i32 [ 1, [[LOOP_HEADER_SPLIT_US_POSTLOOP]] ], [ [[INNER_IV_NEXT_POSTLOOP:%.*]], [[INNER_LOOP_POSTLOOP]] ]77; CHECK-NEXT:    [[INNER_IV_NEXT_POSTLOOP]] = add nuw nsw i32 [[INNER_IV_POSTLOOP]], 178; CHECK-NEXT:    [[INNER_COND_POSTLOOP:%.*]] = icmp ult i32 [[INNER_IV_NEXT_POSTLOOP]], 3179; CHECK-NEXT:    br i1 [[INNER_COND_POSTLOOP]], label [[INNER_LOOP_POSTLOOP]], label [[RANGE_CHECK_BLOCK_POSTLOOP:%.*]]80; CHECK:       range_check_block.postloop:81; CHECK-NEXT:    [[RANGE_CHECK_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], 33182; CHECK-NEXT:    br i1 [[RANGE_CHECK_POSTLOOP]], label [[LOOP_LATCH_POSTLOOP]], label [[DEOPT_LOOPEXIT:%.*]]83; CHECK:       loop_latch.postloop:84; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add i32 [[IV_POSTLOOP]], 185; CHECK-NEXT:    [[LOOP_COND_POSTLOOP:%.*]] = icmp ult i32 [[IV_NEXT_POSTLOOP]], 40086; CHECK-NEXT:    br i1 [[LOOP_COND_POSTLOOP]], label [[LOOP_HEADER_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP0:![0-9]+]], !loop_constrainer.loop.clone [[META5:![0-9]+]]87;88 89entry:90  br label %loop_header91 92loop_header:                            ; preds = %loop_latch, %entry93  %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ]94  %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ]95  %tmp2 = icmp sgt i32 %iv.prev, -196  br i1 %tmp2, label %loop_header.split.us, label %exit97 98loop_header.split.us:                   ; preds = %loop_header99  br label %inner_loop100 101inner_loop:                                   ; preds = %inner_loop, %loop_header.split.us102  %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ]103  %inner_iv_next = add nuw nsw i32 %inner_iv, 1104  %inner_cond = icmp ult i32 %inner_iv_next, 31105  br i1 %inner_cond, label %inner_loop, label %range_check_block106 107exit:                                            ; preds = %loop_latch, %loop_header108  ret void109 110range_check_block:                                          ; preds = %inner_loop111  %range_check = icmp slt i32 %iv, 331112  br i1 %range_check, label %loop_latch, label %deopt113 114loop_latch:                                         ; preds = %range_check_block115  %iv_next = add i32 %iv, 1116  %loop_cond = icmp ult i32 %iv_next, 400117  br i1 %loop_cond, label %loop_header, label %exit118 119deopt:                                          ; preds = %range_check_block120  ret void121}122 123; Similar to test_01, but here the range check is done against 450. No postloop124; is required.125 126define void @test_02() {127; CHECK-LABEL: define void @test_02() {128; CHECK-NEXT:  entry:129; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]130; CHECK:       loop_header:131; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 2, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]132; CHECK-NEXT:    [[IV_PREV:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[IV]], [[LOOP_LATCH]] ]133; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[IV_PREV]], -1134; CHECK-NEXT:    br i1 true, label [[LOOP_HEADER_SPLIT_US:%.*]], label [[EXIT:%.*]]135; CHECK:       loop_header.split.us:136; CHECK-NEXT:    br label [[INNER_LOOP:%.*]]137; CHECK:       inner_loop:138; CHECK-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 1, [[LOOP_HEADER_SPLIT_US]] ], [ [[INNER_IV_NEXT:%.*]], [[INNER_LOOP]] ]139; CHECK-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1140; CHECK-NEXT:    [[INNER_COND:%.*]] = icmp ult i32 [[INNER_IV_NEXT]], 31141; CHECK-NEXT:    br i1 [[INNER_COND]], label [[INNER_LOOP]], label [[RANGE_CHECK_BLOCK:%.*]]142; CHECK:       exit:143; CHECK-NEXT:    ret void144; CHECK:       range_check_block:145; CHECK-NEXT:    [[RANGE_CHECK:%.*]] = icmp slt i32 [[IV]], 450146; CHECK-NEXT:    br i1 true, label [[LOOP_LATCH]], label [[DEOPT:%.*]]147; CHECK:       loop_latch:148; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1149; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 400150; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP_HEADER]], label [[EXIT]]151; CHECK:       deopt:152; CHECK-NEXT:    ret void153;154 155entry:156  br label %loop_header157 158loop_header:                            ; preds = %loop_latch, %entry159  %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ]160  %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ]161  %tmp2 = icmp sgt i32 %iv.prev, -1162  br i1 %tmp2, label %loop_header.split.us, label %exit163 164loop_header.split.us:                   ; preds = %loop_header165  br label %inner_loop166 167inner_loop:                                   ; preds = %inner_loop, %loop_header.split.us168  %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ]169  %inner_iv_next = add nuw nsw i32 %inner_iv, 1170  %inner_cond = icmp ult i32 %inner_iv_next, 31171  br i1 %inner_cond, label %inner_loop, label %range_check_block172 173exit:                                            ; preds = %loop_latch, %loop_header174  ret void175 176range_check_block:                                          ; preds = %inner_loop177  %range_check = icmp slt i32 %iv, 450178  br i1 %range_check, label %loop_latch, label %deopt179 180loop_latch:                                         ; preds = %range_check_block181  %iv_next = add i32 %iv, 1182  %loop_cond = icmp ult i32 %iv_next, 400183  br i1 %loop_cond, label %loop_header, label %exit184 185deopt:                                          ; preds = %range_check_block186  ret void187}188 189; Range check is made against 0, so the safe iteration range is empty. IRCE190; should not apply to the inner loop. The condition %tmp2 can be eliminated.191 192define void @test_03() {193; CHECK-LABEL: define void @test_03() {194; CHECK-NEXT:  entry:195; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]196; CHECK:       loop_header:197; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 2, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]198; CHECK-NEXT:    [[IV_PREV:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[IV]], [[LOOP_LATCH]] ]199; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[IV_PREV]], -1200; CHECK-NEXT:    br i1 true, label [[LOOP_HEADER_SPLIT_US:%.*]], label [[EXIT:%.*]]201; CHECK:       loop_header.split.us:202; CHECK-NEXT:    br label [[INNER_LOOP:%.*]]203; CHECK:       inner_loop:204; CHECK-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 1, [[LOOP_HEADER_SPLIT_US]] ], [ [[INNER_IV_NEXT:%.*]], [[INNER_LOOP]] ]205; CHECK-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1206; CHECK-NEXT:    [[INNER_COND:%.*]] = icmp ult i32 [[INNER_IV_NEXT]], 31207; CHECK-NEXT:    br i1 [[INNER_COND]], label [[INNER_LOOP]], label [[RANGE_CHECK_BLOCK:%.*]]208; CHECK:       exit:209; CHECK-NEXT:    ret void210; CHECK:       range_check_block:211; CHECK-NEXT:    [[RANGE_CHECK:%.*]] = icmp slt i32 [[IV]], 0212; CHECK-NEXT:    br i1 [[RANGE_CHECK]], label [[LOOP_LATCH]], label [[DEOPT:%.*]]213; CHECK:       loop_latch:214; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1215; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 400216; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP_HEADER]], label [[EXIT]]217; CHECK:       deopt:218; CHECK-NEXT:    ret void219;220 221entry:222  br label %loop_header223 224loop_header:                            ; preds = %loop_latch, %entry225  %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ]226  %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ]227  %tmp2 = icmp sgt i32 %iv.prev, -1228  br i1 %tmp2, label %loop_header.split.us, label %exit229 230loop_header.split.us:                   ; preds = %loop_header231  br label %inner_loop232 233inner_loop:                                   ; preds = %inner_loop, %loop_header.split.us234  %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ]235  %inner_iv_next = add nuw nsw i32 %inner_iv, 1236  %inner_cond = icmp ult i32 %inner_iv_next, 31237  br i1 %inner_cond, label %inner_loop, label %range_check_block238 239exit:                                            ; preds = %loop_latch, %loop_header240  ret void241 242range_check_block:                                          ; preds = %inner_loop243  %range_check = icmp slt i32 %iv, 0244  br i1 %range_check, label %loop_latch, label %deopt245 246loop_latch:                                         ; preds = %range_check_block247  %iv_next = add i32 %iv, 1248  %loop_cond = icmp ult i32 %iv_next, 400249  br i1 %loop_cond, label %loop_header, label %exit250 251deopt:                                          ; preds = %range_check_block252  ret void253}254 255; We can also properly eliminate range check against %n which is not always256; known positive.257 258define void @test_04(ptr %p) {259; CHECK-LABEL: define void @test_04260; CHECK-SAME: (ptr [[P:%.*]]) {261; CHECK-NEXT:  entry:262; CHECK-NEXT:    [[N:%.*]] = load i32, ptr [[P]], align 4263; CHECK-NEXT:    [[SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[N]], i32 0)264; CHECK-NEXT:    [[TMP0:%.*]] = sub i32 [[N]], [[SMIN]]265; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[SMIN]], i32 -1)266; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[SMAX]], 1267; CHECK-NEXT:    [[TMP2:%.*]] = mul i32 [[TMP0]], [[TMP1]]268; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP2]], i32 400)269; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.umax.i32(i32 [[UMIN]], i32 2)270; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i32 2, [[EXIT_MAINLOOP_AT]]271; CHECK-NEXT:    br i1 [[TMP3]], label [[LOOP_HEADER_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]272; CHECK:       loop_header.preheader:273; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]274; CHECK:       loop_header:275; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 2, [[LOOP_HEADER_PREHEADER]] ]276; CHECK-NEXT:    [[IV_PREV:%.*]] = phi i32 [ [[IV]], [[LOOP_LATCH]] ], [ 1, [[LOOP_HEADER_PREHEADER]] ]277; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[IV_PREV]], -1278; CHECK-NEXT:    br i1 true, label [[LOOP_HEADER_SPLIT_US:%.*]], label [[EXIT_LOOPEXIT1:%.*]]279; CHECK:       loop_header.split.us:280; CHECK-NEXT:    br label [[INNER_LOOP:%.*]]281; CHECK:       inner_loop:282; CHECK-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 1, [[LOOP_HEADER_SPLIT_US]] ], [ [[INNER_IV_NEXT:%.*]], [[INNER_LOOP]] ]283; CHECK-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1284; CHECK-NEXT:    [[INNER_COND:%.*]] = icmp ult i32 [[INNER_IV_NEXT]], 31285; CHECK-NEXT:    br i1 [[INNER_COND]], label [[INNER_LOOP]], label [[RANGE_CHECK_BLOCK:%.*]]286; CHECK:       exit.loopexit:287; CHECK-NEXT:    br label [[EXIT:%.*]]288; CHECK:       exit.loopexit1:289; CHECK-NEXT:    br label [[EXIT]]290; CHECK:       exit:291; CHECK-NEXT:    ret void292; CHECK:       range_check_block:293; CHECK-NEXT:    [[RANGE_CHECK:%.*]] = icmp slt i32 [[IV]], [[N]]294; CHECK-NEXT:    br i1 true, label [[LOOP_LATCH]], label [[DEOPT_LOOPEXIT2:%.*]]295; CHECK:       loop_latch:296; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1297; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 400298; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 [[IV_NEXT]], [[EXIT_MAINLOOP_AT]]299; CHECK-NEXT:    br i1 [[TMP4]], label [[LOOP_HEADER]], label [[MAIN_EXIT_SELECTOR:%.*]]300; CHECK:       main.exit.selector:301; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[LOOP_LATCH]] ]302; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP_LATCH]] ]303; CHECK-NEXT:    [[TMP5:%.*]] = icmp ult i32 [[IV_NEXT_LCSSA]], 400304; CHECK-NEXT:    br i1 [[TMP5]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT]]305; CHECK:       main.pseudo.exit:306; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ 2, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]307; CHECK-NEXT:    [[IV_PREV_COPY:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]308; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 2, [[ENTRY]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]309; CHECK-NEXT:    br label [[POSTLOOP:%.*]]310; CHECK:       deopt.loopexit:311; CHECK-NEXT:    br label [[DEOPT:%.*]]312; CHECK:       deopt.loopexit2:313; CHECK-NEXT:    br label [[DEOPT]]314; CHECK:       deopt:315; CHECK-NEXT:    ret void316; CHECK:       postloop:317; CHECK-NEXT:    br label [[LOOP_HEADER_POSTLOOP:%.*]]318; CHECK:       loop_header.postloop:319; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i32 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[LOOP_LATCH_POSTLOOP:%.*]] ]320; CHECK-NEXT:    [[IV_PREV_POSTLOOP:%.*]] = phi i32 [ [[IV_PREV_COPY]], [[POSTLOOP]] ], [ [[IV_POSTLOOP]], [[LOOP_LATCH_POSTLOOP]] ]321; CHECK-NEXT:    [[TMP2_POSTLOOP:%.*]] = icmp sgt i32 [[IV_PREV_POSTLOOP]], -1322; CHECK-NEXT:    br i1 [[TMP2_POSTLOOP]], label [[LOOP_HEADER_SPLIT_US_POSTLOOP:%.*]], label [[EXIT_LOOPEXIT:%.*]]323; CHECK:       loop_header.split.us.postloop:324; CHECK-NEXT:    br label [[INNER_LOOP_POSTLOOP:%.*]]325; CHECK:       inner_loop.postloop:326; CHECK-NEXT:    [[INNER_IV_POSTLOOP:%.*]] = phi i32 [ 1, [[LOOP_HEADER_SPLIT_US_POSTLOOP]] ], [ [[INNER_IV_NEXT_POSTLOOP:%.*]], [[INNER_LOOP_POSTLOOP]] ]327; CHECK-NEXT:    [[INNER_IV_NEXT_POSTLOOP]] = add nuw nsw i32 [[INNER_IV_POSTLOOP]], 1328; CHECK-NEXT:    [[INNER_COND_POSTLOOP:%.*]] = icmp ult i32 [[INNER_IV_NEXT_POSTLOOP]], 31329; CHECK-NEXT:    br i1 [[INNER_COND_POSTLOOP]], label [[INNER_LOOP_POSTLOOP]], label [[RANGE_CHECK_BLOCK_POSTLOOP:%.*]]330; CHECK:       range_check_block.postloop:331; CHECK-NEXT:    [[RANGE_CHECK_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], [[N]]332; CHECK-NEXT:    br i1 [[RANGE_CHECK_POSTLOOP]], label [[LOOP_LATCH_POSTLOOP]], label [[DEOPT_LOOPEXIT:%.*]]333; CHECK:       loop_latch.postloop:334; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add i32 [[IV_POSTLOOP]], 1335; CHECK-NEXT:    [[LOOP_COND_POSTLOOP:%.*]] = icmp ult i32 [[IV_NEXT_POSTLOOP]], 400336; CHECK-NEXT:    br i1 [[LOOP_COND_POSTLOOP]], label [[LOOP_HEADER_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP6:![0-9]+]], !loop_constrainer.loop.clone [[META5]]337;338 339entry:340  %n = load i32, ptr %p341  br label %loop_header342 343loop_header:                            ; preds = %loop_latch, %entry344  %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ]345  %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ]346  %tmp2 = icmp sgt i32 %iv.prev, -1347  br i1 %tmp2, label %loop_header.split.us, label %exit348 349loop_header.split.us:                   ; preds = %loop_header350  br label %inner_loop351 352inner_loop:                                   ; preds = %inner_loop, %loop_header.split.us353  %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ]354  %inner_iv_next = add nuw nsw i32 %inner_iv, 1355  %inner_cond = icmp ult i32 %inner_iv_next, 31356  br i1 %inner_cond, label %inner_loop, label %range_check_block357 358exit:                                            ; preds = %loop_latch, %loop_header359  ret void360 361range_check_block:                                          ; preds = %inner_loop362  %range_check = icmp slt i32 %iv, %n363  br i1 %range_check, label %loop_latch, label %deopt364 365loop_latch:                                         ; preds = %range_check_block366  %iv_next = add i32 %iv, 1367  %loop_cond = icmp ult i32 %iv_next, 400368  br i1 %loop_cond, label %loop_header, label %exit369 370deopt:                                          ; preds = %range_check_block371  ret void372}373 374; Same as test_04, but range guarantees that %n is positive. So we can safely375; intersect ranges (with insertion of postloop).376 377define void @test_05(ptr %p) {378; CHECK-LABEL: define void @test_05379; CHECK-SAME: (ptr [[P:%.*]]) {380; CHECK-NEXT:  entry:381; CHECK-NEXT:    [[N:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG7:![0-9]+]]382; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.umax.i32(i32 [[N]], i32 2)383; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 2, [[EXIT_MAINLOOP_AT]]384; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_HEADER_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]385; CHECK:       loop_header.preheader:386; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]387; CHECK:       loop_header:388; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 2, [[LOOP_HEADER_PREHEADER]] ]389; CHECK-NEXT:    [[IV_PREV:%.*]] = phi i32 [ [[IV]], [[LOOP_LATCH]] ], [ 1, [[LOOP_HEADER_PREHEADER]] ]390; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[IV_PREV]], -1391; CHECK-NEXT:    br i1 true, label [[LOOP_HEADER_SPLIT_US:%.*]], label [[EXIT_LOOPEXIT1:%.*]]392; CHECK:       loop_header.split.us:393; CHECK-NEXT:    br label [[INNER_LOOP:%.*]]394; CHECK:       inner_loop:395; CHECK-NEXT:    [[INNER_IV:%.*]] = phi i32 [ 1, [[LOOP_HEADER_SPLIT_US]] ], [ [[INNER_IV_NEXT:%.*]], [[INNER_LOOP]] ]396; CHECK-NEXT:    [[INNER_IV_NEXT]] = add nuw nsw i32 [[INNER_IV]], 1397; CHECK-NEXT:    [[INNER_COND:%.*]] = icmp ult i32 [[INNER_IV_NEXT]], 31398; CHECK-NEXT:    br i1 [[INNER_COND]], label [[INNER_LOOP]], label [[RANGE_CHECK_BLOCK:%.*]]399; CHECK:       exit.loopexit:400; CHECK-NEXT:    br label [[EXIT:%.*]]401; CHECK:       exit.loopexit1:402; CHECK-NEXT:    br label [[EXIT]]403; CHECK:       exit:404; CHECK-NEXT:    ret void405; CHECK:       range_check_block:406; CHECK-NEXT:    [[RANGE_CHECK:%.*]] = icmp slt i32 [[IV]], [[N]]407; CHECK-NEXT:    br i1 true, label [[LOOP_LATCH]], label [[DEOPT_LOOPEXIT2:%.*]]408; CHECK:       loop_latch:409; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1410; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 400411; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[IV_NEXT]], [[EXIT_MAINLOOP_AT]]412; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_HEADER]], label [[MAIN_EXIT_SELECTOR:%.*]]413; CHECK:       main.exit.selector:414; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[LOOP_LATCH]] ]415; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[LOOP_LATCH]] ]416; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[IV_NEXT_LCSSA]], 400417; CHECK-NEXT:    br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT]]418; CHECK:       main.pseudo.exit:419; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ 2, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]420; CHECK-NEXT:    [[IV_PREV_COPY:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]421; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 2, [[ENTRY]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]422; CHECK-NEXT:    br label [[POSTLOOP:%.*]]423; CHECK:       deopt.loopexit:424; CHECK-NEXT:    br label [[DEOPT:%.*]]425; CHECK:       deopt.loopexit2:426; CHECK-NEXT:    br label [[DEOPT]]427; CHECK:       deopt:428; CHECK-NEXT:    ret void429; CHECK:       postloop:430; CHECK-NEXT:    br label [[LOOP_HEADER_POSTLOOP:%.*]]431; CHECK:       loop_header.postloop:432; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i32 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[LOOP_LATCH_POSTLOOP:%.*]] ]433; CHECK-NEXT:    [[IV_PREV_POSTLOOP:%.*]] = phi i32 [ [[IV_PREV_COPY]], [[POSTLOOP]] ], [ [[IV_POSTLOOP]], [[LOOP_LATCH_POSTLOOP]] ]434; CHECK-NEXT:    [[TMP2_POSTLOOP:%.*]] = icmp sgt i32 [[IV_PREV_POSTLOOP]], -1435; CHECK-NEXT:    br i1 [[TMP2_POSTLOOP]], label [[LOOP_HEADER_SPLIT_US_POSTLOOP:%.*]], label [[EXIT_LOOPEXIT:%.*]]436; CHECK:       loop_header.split.us.postloop:437; CHECK-NEXT:    br label [[INNER_LOOP_POSTLOOP:%.*]]438; CHECK:       inner_loop.postloop:439; CHECK-NEXT:    [[INNER_IV_POSTLOOP:%.*]] = phi i32 [ 1, [[LOOP_HEADER_SPLIT_US_POSTLOOP]] ], [ [[INNER_IV_NEXT_POSTLOOP:%.*]], [[INNER_LOOP_POSTLOOP]] ]440; CHECK-NEXT:    [[INNER_IV_NEXT_POSTLOOP]] = add nuw nsw i32 [[INNER_IV_POSTLOOP]], 1441; CHECK-NEXT:    [[INNER_COND_POSTLOOP:%.*]] = icmp ult i32 [[INNER_IV_NEXT_POSTLOOP]], 31442; CHECK-NEXT:    br i1 [[INNER_COND_POSTLOOP]], label [[INNER_LOOP_POSTLOOP]], label [[RANGE_CHECK_BLOCK_POSTLOOP:%.*]]443; CHECK:       range_check_block.postloop:444; CHECK-NEXT:    [[RANGE_CHECK_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], [[N]]445; CHECK-NEXT:    br i1 [[RANGE_CHECK_POSTLOOP]], label [[LOOP_LATCH_POSTLOOP]], label [[DEOPT_LOOPEXIT:%.*]]446; CHECK:       loop_latch.postloop:447; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add i32 [[IV_POSTLOOP]], 1448; CHECK-NEXT:    [[LOOP_COND_POSTLOOP:%.*]] = icmp ult i32 [[IV_NEXT_POSTLOOP]], 400449; CHECK-NEXT:    br i1 [[LOOP_COND_POSTLOOP]], label [[LOOP_HEADER_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP8:![0-9]+]], !loop_constrainer.loop.clone [[META5]]450;451 452entry:453  %n = load i32, ptr %p, !range !0454  br label %loop_header455 456loop_header:                            ; preds = %loop_latch, %entry457  %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ]458  %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ]459  %tmp2 = icmp sgt i32 %iv.prev, -1460  br i1 %tmp2, label %loop_header.split.us, label %exit461 462loop_header.split.us:                   ; preds = %loop_header463  br label %inner_loop464 465inner_loop:                                   ; preds = %inner_loop, %loop_header.split.us466  %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ]467  %inner_iv_next = add nuw nsw i32 %inner_iv, 1468  %inner_cond = icmp ult i32 %inner_iv_next, 31469  br i1 %inner_cond, label %inner_loop, label %range_check_block470 471exit:                                            ; preds = %loop_latch, %loop_header472  ret void473 474range_check_block:                                          ; preds = %inner_loop475  %range_check = icmp slt i32 %iv, %n476  br i1 %range_check, label %loop_latch, label %deopt477 478loop_latch:                                         ; preds = %range_check_block479  %iv_next = add i32 %iv, 1480  %loop_cond = icmp ult i32 %iv_next, 400481  br i1 %loop_cond, label %loop_header, label %exit482 483deopt:                                          ; preds = %range_check_block484  ret void485}486 487!0 = !{i32 0, i32 50}488;.489; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]], [[META3:![0-9]+]], [[META4:![0-9]+]]}490; CHECK: [[META1]] = !{!"llvm.loop.unroll.disable"}491; CHECK: [[META2]] = !{!"llvm.loop.vectorize.enable", i1 false}492; CHECK: [[META3]] = !{!"llvm.loop.licm_versioning.disable"}493; CHECK: [[META4]] = !{!"llvm.loop.distribute.enable", i1 false}494; CHECK: [[META5]] = !{}495; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META1]], [[META2]], [[META3]], [[META4]]}496; CHECK: [[RNG7]] = !{i32 0, i32 50}497; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META1]], [[META2]], [[META3]], [[META4]]}498;.499