1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 2; RUN: opt -verify-loop-info -irce-print-changed-loops -passes=irce -S < %s 2>&1 | FileCheck %s 3; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,irce' -S < %s 2>&1 | FileCheck %s 4 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 in 12; range of [2, 400) and the range check is done against value 331. Due to a bug 13; in range intersection IRCE manages to eliminate the range check without 14; inserting a postloop, which is incorrect. We treat the range of this test as 15; an unsigned range and are able to intersect ranges correctly and insert a 16; 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]], -1 28; 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]], 1 34; CHECK-NEXT: [[INNER_COND:%.*]] = icmp ult i32 [[INNER_IV_NEXT]], 31 35; 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 void 42; CHECK: range_check_block: 43; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp slt i32 [[IV]], 331 44; CHECK-NEXT: br i1 true, label [[LOOP_LATCH]], label [[DEOPT_LOOPEXIT2:%.*]] 45; CHECK: loop_latch: 46; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 47; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 400 48; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[IV_NEXT]], 331 49; 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]], 400 54; 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 void 66; 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]], -1 72; 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]], 1 78; CHECK-NEXT: [[INNER_COND_POSTLOOP:%.*]] = icmp ult i32 [[INNER_IV_NEXT_POSTLOOP]], 31 79; 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]], 331 82; 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]], 1 85; CHECK-NEXT: [[LOOP_COND_POSTLOOP:%.*]] = icmp ult i32 [[IV_NEXT_POSTLOOP]], 400 86; 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_header 91 92loop_header: ; preds = %loop_latch, %entry 93 %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, -1 96 br i1 %tmp2, label %loop_header.split.us, label %exit 97 98loop_header.split.us: ; preds = %loop_header 99 br label %inner_loop 100 101inner_loop: ; preds = %inner_loop, %loop_header.split.us 102 %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ] 103 %inner_iv_next = add nuw nsw i32 %inner_iv, 1 104 %inner_cond = icmp ult i32 %inner_iv_next, 31 105 br i1 %inner_cond, label %inner_loop, label %range_check_block 106 107exit: ; preds = %loop_latch, %loop_header 108 ret void 109 110range_check_block: ; preds = %inner_loop 111 %range_check = icmp slt i32 %iv, 331 112 br i1 %range_check, label %loop_latch, label %deopt 113 114loop_latch: ; preds = %range_check_block 115 %iv_next = add i32 %iv, 1 116 %loop_cond = icmp ult i32 %iv_next, 400 117 br i1 %loop_cond, label %loop_header, label %exit 118 119deopt: ; preds = %range_check_block 120 ret void 121} 122 123; Similar to test_01, but here the range check is done against 450. No postloop 124; 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]], -1 134; 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]], 1 140; CHECK-NEXT: [[INNER_COND:%.*]] = icmp ult i32 [[INNER_IV_NEXT]], 31 141; CHECK-NEXT: br i1 [[INNER_COND]], label [[INNER_LOOP]], label [[RANGE_CHECK_BLOCK:%.*]] 142; CHECK: exit: 143; CHECK-NEXT: ret void 144; CHECK: range_check_block: 145; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp slt i32 [[IV]], 450 146; CHECK-NEXT: br i1 true, label [[LOOP_LATCH]], label [[DEOPT:%.*]] 147; CHECK: loop_latch: 148; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 149; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 400 150; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP_HEADER]], label [[EXIT]] 151; CHECK: deopt: 152; CHECK-NEXT: ret void 153; 154 155entry: 156 br label %loop_header 157 158loop_header: ; preds = %loop_latch, %entry 159 %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, -1 162 br i1 %tmp2, label %loop_header.split.us, label %exit 163 164loop_header.split.us: ; preds = %loop_header 165 br label %inner_loop 166 167inner_loop: ; preds = %inner_loop, %loop_header.split.us 168 %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ] 169 %inner_iv_next = add nuw nsw i32 %inner_iv, 1 170 %inner_cond = icmp ult i32 %inner_iv_next, 31 171 br i1 %inner_cond, label %inner_loop, label %range_check_block 172 173exit: ; preds = %loop_latch, %loop_header 174 ret void 175 176range_check_block: ; preds = %inner_loop 177 %range_check = icmp slt i32 %iv, 450 178 br i1 %range_check, label %loop_latch, label %deopt 179 180loop_latch: ; preds = %range_check_block 181 %iv_next = add i32 %iv, 1 182 %loop_cond = icmp ult i32 %iv_next, 400 183 br i1 %loop_cond, label %loop_header, label %exit 184 185deopt: ; preds = %range_check_block 186 ret void 187} 188 189; Range check is made against 0, so the safe iteration range is empty. IRCE 190; 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]], -1 200; 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]], 1 206; CHECK-NEXT: [[INNER_COND:%.*]] = icmp ult i32 [[INNER_IV_NEXT]], 31 207; CHECK-NEXT: br i1 [[INNER_COND]], label [[INNER_LOOP]], label [[RANGE_CHECK_BLOCK:%.*]] 208; CHECK: exit: 209; CHECK-NEXT: ret void 210; CHECK: range_check_block: 211; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp slt i32 [[IV]], 0 212; CHECK-NEXT: br i1 [[RANGE_CHECK]], label [[LOOP_LATCH]], label [[DEOPT:%.*]] 213; CHECK: loop_latch: 214; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 215; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 400 216; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP_HEADER]], label [[EXIT]] 217; CHECK: deopt: 218; CHECK-NEXT: ret void 219; 220 221entry: 222 br label %loop_header 223 224loop_header: ; preds = %loop_latch, %entry 225 %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, -1 228 br i1 %tmp2, label %loop_header.split.us, label %exit 229 230loop_header.split.us: ; preds = %loop_header 231 br label %inner_loop 232 233inner_loop: ; preds = %inner_loop, %loop_header.split.us 234 %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ] 235 %inner_iv_next = add nuw nsw i32 %inner_iv, 1 236 %inner_cond = icmp ult i32 %inner_iv_next, 31 237 br i1 %inner_cond, label %inner_loop, label %range_check_block 238 239exit: ; preds = %loop_latch, %loop_header 240 ret void 241 242range_check_block: ; preds = %inner_loop 243 %range_check = icmp slt i32 %iv, 0 244 br i1 %range_check, label %loop_latch, label %deopt 245 246loop_latch: ; preds = %range_check_block 247 %iv_next = add i32 %iv, 1 248 %loop_cond = icmp ult i32 %iv_next, 400 249 br i1 %loop_cond, label %loop_header, label %exit 250 251deopt: ; preds = %range_check_block 252 ret void 253} 254 255; We can also properly eliminate range check against %n which is not always 256; known positive. 257 258define void @test_04(ptr %p) { 259; CHECK-LABEL: define void @test_04 260; CHECK-SAME: (ptr [[P:%.*]]) { 261; CHECK-NEXT: entry: 262; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[P]], align 4 263; 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]], 1 267; 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]], -1 278; 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]], 1 284; CHECK-NEXT: [[INNER_COND:%.*]] = icmp ult i32 [[INNER_IV_NEXT]], 31 285; 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 void 292; 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]], 1 297; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 400 298; 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]], 400 304; 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 void 316; 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]], -1 322; 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]], 1 328; CHECK-NEXT: [[INNER_COND_POSTLOOP:%.*]] = icmp ult i32 [[INNER_IV_NEXT_POSTLOOP]], 31 329; 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]], 1 335; CHECK-NEXT: [[LOOP_COND_POSTLOOP:%.*]] = icmp ult i32 [[IV_NEXT_POSTLOOP]], 400 336; 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 %p 341 br label %loop_header 342 343loop_header: ; preds = %loop_latch, %entry 344 %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, -1 347 br i1 %tmp2, label %loop_header.split.us, label %exit 348 349loop_header.split.us: ; preds = %loop_header 350 br label %inner_loop 351 352inner_loop: ; preds = %inner_loop, %loop_header.split.us 353 %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ] 354 %inner_iv_next = add nuw nsw i32 %inner_iv, 1 355 %inner_cond = icmp ult i32 %inner_iv_next, 31 356 br i1 %inner_cond, label %inner_loop, label %range_check_block 357 358exit: ; preds = %loop_latch, %loop_header 359 ret void 360 361range_check_block: ; preds = %inner_loop 362 %range_check = icmp slt i32 %iv, %n 363 br i1 %range_check, label %loop_latch, label %deopt 364 365loop_latch: ; preds = %range_check_block 366 %iv_next = add i32 %iv, 1 367 %loop_cond = icmp ult i32 %iv_next, 400 368 br i1 %loop_cond, label %loop_header, label %exit 369 370deopt: ; preds = %range_check_block 371 ret void 372} 373 374; Same as test_04, but range guarantees that %n is positive. So we can safely 375; intersect ranges (with insertion of postloop). 376 377define void @test_05(ptr %p) { 378; CHECK-LABEL: define void @test_05 379; 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]], -1 391; 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]], 1 397; CHECK-NEXT: [[INNER_COND:%.*]] = icmp ult i32 [[INNER_IV_NEXT]], 31 398; 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 void 405; 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]], 1 410; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 400 411; 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]], 400 417; 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 void 429; 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]], -1 435; 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]], 1 441; CHECK-NEXT: [[INNER_COND_POSTLOOP:%.*]] = icmp ult i32 [[INNER_IV_NEXT_POSTLOOP]], 31 442; 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]], 1 448; CHECK-NEXT: [[LOOP_COND_POSTLOOP:%.*]] = icmp ult i32 [[IV_NEXT_POSTLOOP]], 400 449; 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 !0 454 br label %loop_header 455 456loop_header: ; preds = %loop_latch, %entry 457 %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, -1 460 br i1 %tmp2, label %loop_header.split.us, label %exit 461 462loop_header.split.us: ; preds = %loop_header 463 br label %inner_loop 464 465inner_loop: ; preds = %inner_loop, %loop_header.split.us 466 %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ] 467 %inner_iv_next = add nuw nsw i32 %inner_iv, 1 468 %inner_cond = icmp ult i32 %inner_iv_next, 31 469 br i1 %inner_cond, label %inner_loop, label %range_check_block 470 471exit: ; preds = %loop_latch, %loop_header 472 ret void 473 474range_check_block: ; preds = %inner_loop 475 %range_check = icmp slt i32 %iv, %n 476 br i1 %range_check, label %loop_latch, label %deopt 477 478loop_latch: ; preds = %range_check_block 479 %iv_next = add i32 %iv, 1 480 %loop_cond = icmp ult i32 %iv_next, 400 481 br i1 %loop_cond, label %loop_header, label %exit 482 483deopt: ; preds = %range_check_block 484 ret void 485} 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