brintos

brintos / llvm-project-archived public Read only

0
0
Text · 48.5 KiB · 749c17d Raw
991 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; 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: irce: in function test_01: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>6; CHECK: irce: in function test_02: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>7; CHECK: irce: in function test_03: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>8; CHECK: irce: in function test_04: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>9; CHECK: irce: in function test_05: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>10; CHECK: irce: in function test_06: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>11; CHECK-NOT: irce: in function test_07: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>12; CHECK: irce: in function test_08: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>13 14; IV = 0; IV <s 100; IV += 7; 0 <= Len <= 50. IRCE is allowed.15define void @test_01(ptr %arr, ptr %a_len_ptr) {16; CHECK-LABEL: define void @test_0117; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {18; CHECK-NEXT:  entry:19; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0:![0-9]+]]20; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 0, [[EXIT_MAINLOOP_AT]]21; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]22; CHECK:       loop.preheader:23; CHECK-NEXT:    br label [[LOOP:%.*]]24; CHECK:       loop:25; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]26; CHECK-NEXT:    [[IDX_NEXT]] = add nsw i32 [[IDX]], 727; CHECK-NEXT:    [[ABC:%.*]] = icmp slt i32 [[IDX]], [[EXIT_MAINLOOP_AT]]28; CHECK-NEXT:    br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]29; CHECK:       in.bounds:30; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]31; CHECK-NEXT:    store i32 0, ptr [[ADDR]], align 432; CHECK-NEXT:    [[NEXT:%.*]] = icmp slt i32 [[IDX_NEXT]], 10033; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]34; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]35; CHECK:       main.exit.selector:36; CHECK-NEXT:    [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]37; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[IDX_NEXT_LCSSA]], 10038; CHECK-NEXT:    br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]39; CHECK:       main.pseudo.exit:40; CHECK-NEXT:    [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]41; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]42; CHECK-NEXT:    br label [[POSTLOOP:%.*]]43; CHECK:       out.of.bounds.loopexit:44; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]45; CHECK:       out.of.bounds.loopexit1:46; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]47; CHECK:       out.of.bounds:48; CHECK-NEXT:    ret void49; CHECK:       exit.loopexit:50; CHECK-NEXT:    br label [[EXIT]]51; CHECK:       exit:52; CHECK-NEXT:    ret void53; CHECK:       postloop:54; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]55; CHECK:       loop.postloop:56; CHECK-NEXT:    [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]57; CHECK-NEXT:    [[IDX_NEXT_POSTLOOP]] = add i32 [[IDX_POSTLOOP]], 758; CHECK-NEXT:    [[ABC_POSTLOOP:%.*]] = icmp slt i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]59; CHECK-NEXT:    br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]60; CHECK:       in.bounds.postloop:61; CHECK-NEXT:    [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]62; CHECK-NEXT:    store i32 0, ptr [[ADDR_POSTLOOP]], align 463; CHECK-NEXT:    [[NEXT_POSTLOOP:%.*]] = icmp slt i32 [[IDX_NEXT_POSTLOOP]], 10064; CHECK-NEXT:    br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP1:![0-9]+]], !loop_constrainer.loop.clone !665;66 67entry:68  %len = load i32, ptr %a_len_ptr, !range !069  br label %loop70 71loop:72  %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]73  %idx.next = add i32 %idx, 774  %abc = icmp slt i32 %idx, %len75  br i1 %abc, label %in.bounds, label %out.of.bounds76 77in.bounds:78  %addr = getelementptr i32, ptr %arr, i32 %idx79  store i32 0, ptr %addr80  %next = icmp slt i32 %idx.next, 10081  br i1 %next, label %loop, label %exit82 83out.of.bounds:84  ret void85 86exit:87  ret void88}89 90; IV = 0; IV <s MAX_INT - 7; IV += 7; 0 <= Len <= 50. IRCE is allowed.91define void @test_02(ptr %arr, ptr %a_len_ptr) {92; CHECK-LABEL: define void @test_0293; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {94; CHECK-NEXT:  entry:95; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]96; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 0, [[EXIT_MAINLOOP_AT]]97; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]98; CHECK:       loop.preheader:99; CHECK-NEXT:    br label [[LOOP:%.*]]100; CHECK:       loop:101; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]102; CHECK-NEXT:    [[IDX_NEXT]] = add nsw i32 [[IDX]], 7103; CHECK-NEXT:    [[ABC:%.*]] = icmp slt i32 [[IDX]], [[EXIT_MAINLOOP_AT]]104; CHECK-NEXT:    br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]105; CHECK:       in.bounds:106; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]107; CHECK-NEXT:    store i32 0, ptr [[ADDR]], align 4108; CHECK-NEXT:    [[NEXT:%.*]] = icmp slt i32 [[IDX_NEXT]], 2147483640109; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]110; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]111; CHECK:       main.exit.selector:112; CHECK-NEXT:    [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]113; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[IDX_NEXT_LCSSA]], 2147483640114; CHECK-NEXT:    br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]115; CHECK:       main.pseudo.exit:116; CHECK-NEXT:    [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]117; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]118; CHECK-NEXT:    br label [[POSTLOOP:%.*]]119; CHECK:       out.of.bounds.loopexit:120; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]121; CHECK:       out.of.bounds.loopexit1:122; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]123; CHECK:       out.of.bounds:124; CHECK-NEXT:    ret void125; CHECK:       exit.loopexit:126; CHECK-NEXT:    br label [[EXIT]]127; CHECK:       exit:128; CHECK-NEXT:    ret void129; CHECK:       postloop:130; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]131; CHECK:       loop.postloop:132; CHECK-NEXT:    [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]133; CHECK-NEXT:    [[IDX_NEXT_POSTLOOP]] = add i32 [[IDX_POSTLOOP]], 7134; CHECK-NEXT:    [[ABC_POSTLOOP:%.*]] = icmp slt i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]135; CHECK-NEXT:    br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]136; CHECK:       in.bounds.postloop:137; CHECK-NEXT:    [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]138; CHECK-NEXT:    store i32 0, ptr [[ADDR_POSTLOOP]], align 4139; CHECK-NEXT:    [[NEXT_POSTLOOP:%.*]] = icmp slt i32 [[IDX_NEXT_POSTLOOP]], 2147483640140; CHECK-NEXT:    br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP7:![0-9]+]], !loop_constrainer.loop.clone !6141;142 143entry:144  %len = load i32, ptr %a_len_ptr, !range !0145  br label %loop146 147loop:148  %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]149  %idx.next = add i32 %idx, 7150  %abc = icmp slt i32 %idx, %len151  br i1 %abc, label %in.bounds, label %out.of.bounds152 153in.bounds:154  %addr = getelementptr i32, ptr %arr, i32 %idx155  store i32 0, ptr %addr156  %next = icmp slt i32 %idx.next, 2147483640157  br i1 %next, label %loop, label %exit158 159out.of.bounds:160  ret void161 162exit:163  ret void164}165 166; IV = 0; IV <s MAX_INT; IV += 7; 0 <= Len <= MAX_INT - 7. This is the greatest167; value of Len for which IRCE is allowed.168define void @test_03(ptr %arr, ptr %a_len_ptr) {169; CHECK-LABEL: define void @test_03170; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {171; CHECK-NEXT:  entry:172; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG8:![0-9]+]]173; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 0, [[EXIT_MAINLOOP_AT]]174; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]175; CHECK:       loop.preheader:176; CHECK-NEXT:    br label [[LOOP:%.*]]177; CHECK:       loop:178; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]179; CHECK-NEXT:    [[IDX_NEXT]] = add nsw i32 [[IDX]], 7180; CHECK-NEXT:    [[ABC:%.*]] = icmp slt i32 [[IDX]], [[EXIT_MAINLOOP_AT]]181; CHECK-NEXT:    br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]182; CHECK:       in.bounds:183; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]184; CHECK-NEXT:    store i32 0, ptr [[ADDR]], align 4185; CHECK-NEXT:    [[NEXT:%.*]] = icmp slt i32 [[IDX_NEXT]], 2147483647186; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]187; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]188; CHECK:       main.exit.selector:189; CHECK-NEXT:    [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]190; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[IDX_NEXT_LCSSA]], 2147483647191; CHECK-NEXT:    br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]192; CHECK:       main.pseudo.exit:193; CHECK-NEXT:    [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]194; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]195; CHECK-NEXT:    br label [[POSTLOOP:%.*]]196; CHECK:       out.of.bounds.loopexit:197; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]198; CHECK:       out.of.bounds.loopexit1:199; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]200; CHECK:       out.of.bounds:201; CHECK-NEXT:    ret void202; CHECK:       exit.loopexit:203; CHECK-NEXT:    br label [[EXIT]]204; CHECK:       exit:205; CHECK-NEXT:    ret void206; CHECK:       postloop:207; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]208; CHECK:       loop.postloop:209; CHECK-NEXT:    [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]210; CHECK-NEXT:    [[IDX_NEXT_POSTLOOP]] = add i32 [[IDX_POSTLOOP]], 7211; CHECK-NEXT:    [[ABC_POSTLOOP:%.*]] = icmp slt i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]212; CHECK-NEXT:    br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]213; CHECK:       in.bounds.postloop:214; CHECK-NEXT:    [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]215; CHECK-NEXT:    store i32 0, ptr [[ADDR_POSTLOOP]], align 4216; CHECK-NEXT:    [[NEXT_POSTLOOP:%.*]] = icmp slt i32 [[IDX_NEXT_POSTLOOP]], 2147483647217; CHECK-NEXT:    br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP9:![0-9]+]], !loop_constrainer.loop.clone !6218;219 220entry:221  %len = load i32, ptr %a_len_ptr, !range !1222  br label %loop223 224loop:225  %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]226  %idx.next = add i32 %idx, 7227  %abc = icmp slt i32 %idx, %len228  br i1 %abc, label %in.bounds, label %out.of.bounds229 230in.bounds:231  %addr = getelementptr i32, ptr %arr, i32 %idx232  store i32 0, ptr %addr233  %next = icmp slt i32 %idx.next, 2147483647234  br i1 %next, label %loop, label %exit235 236out.of.bounds:237  ret void238 239exit:240  ret void241}242 243; IV = 0; IV <s MAX_INT; IV += 7; 0 <= Len <= MAX_INT - 6. IRCE is allowed244; because the branch would fail once idx.next == MAX_INT - 1 keeping the245; access in bounds.246define void @test_04(ptr %arr, ptr %a_len_ptr) {247; CHECK-LABEL: define void @test_04248; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {249; CHECK-NEXT:  entry:250; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG10:![0-9]+]]251; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 0, [[EXIT_MAINLOOP_AT]]252; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]253; CHECK:       loop.preheader:254; CHECK-NEXT:    br label [[LOOP:%.*]]255; CHECK:       loop:256; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]257; CHECK-NEXT:    [[IDX_NEXT]] = add nsw i32 [[IDX]], 7258; CHECK-NEXT:    [[ABC:%.*]] = icmp slt i32 [[IDX]], [[EXIT_MAINLOOP_AT]]259; CHECK-NEXT:    br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]260; CHECK:       in.bounds:261; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]262; CHECK-NEXT:    store i32 0, ptr [[ADDR]], align 4263; CHECK-NEXT:    [[NEXT:%.*]] = icmp slt i32 [[IDX_NEXT]], 2147483647264; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]265; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]266; CHECK:       main.exit.selector:267; CHECK-NEXT:    [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]268; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[IDX_NEXT_LCSSA]], 2147483647269; CHECK-NEXT:    br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]270; CHECK:       main.pseudo.exit:271; CHECK-NEXT:    [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]272; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]273; CHECK-NEXT:    br label [[POSTLOOP:%.*]]274; CHECK:       out.of.bounds.loopexit:275; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]276; CHECK:       out.of.bounds.loopexit1:277; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]278; CHECK:       out.of.bounds:279; CHECK-NEXT:    ret void280; CHECK:       exit.loopexit:281; CHECK-NEXT:    br label [[EXIT]]282; CHECK:       exit:283; CHECK-NEXT:    ret void284; CHECK:       postloop:285; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]286; CHECK:       loop.postloop:287; CHECK-NEXT:    [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]288; CHECK-NEXT:    [[IDX_NEXT_POSTLOOP]] = add i32 [[IDX_POSTLOOP]], 7289; CHECK-NEXT:    [[ABC_POSTLOOP:%.*]] = icmp slt i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]290; CHECK-NEXT:    br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]291; CHECK:       in.bounds.postloop:292; CHECK-NEXT:    [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]293; CHECK-NEXT:    store i32 0, ptr [[ADDR_POSTLOOP]], align 4294; CHECK-NEXT:    [[NEXT_POSTLOOP:%.*]] = icmp slt i32 [[IDX_NEXT_POSTLOOP]], 2147483647295; CHECK-NEXT:    br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP11:![0-9]+]], !loop_constrainer.loop.clone !6296;297 298 299 300entry:301  %len = load i32, ptr %a_len_ptr, !range !2302  br label %loop303 304loop:305  %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]306  %idx.next = add i32 %idx, 7307  %abc = icmp slt i32 %idx, %len308  br i1 %abc, label %in.bounds, label %out.of.bounds309 310in.bounds:311  %addr = getelementptr i32, ptr %arr, i32 %idx312  store i32 0, ptr %addr313  %next = icmp slt i32 %idx.next, 2147483647314  br i1 %next, label %loop, label %exit315 316out.of.bounds:317  ret void318 319exit:320  ret void321}322 323; IV = 100; IV >s -1; IV -= 7; 0 <= Len <= 50. IRCE is allowed.324define void @test_05(ptr %arr, ptr %a_len_ptr) {325; CHECK-LABEL: define void @test_05326; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {327; CHECK-NEXT:  entry:328; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]329; CHECK-NEXT:    [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[LEN]], -1330; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 100, [[EXIT_PRELOOP_AT]]331; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]332; CHECK:       loop.preloop.preheader:333; CHECK-NEXT:    br label [[LOOP_PRELOOP:%.*]]334; CHECK:       mainloop:335; CHECK-NEXT:    br label [[LOOP:%.*]]336; CHECK:       loop:337; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_PRELOOP_COPY:%.*]], [[MAINLOOP:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]338; CHECK-NEXT:    [[IDX_NEXT]] = add nsw i32 [[IDX]], -7339; CHECK-NEXT:    [[ABC:%.*]] = icmp slt i32 [[IDX]], [[LEN]]340; CHECK-NEXT:    br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]341; CHECK:       in.bounds:342; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]343; CHECK-NEXT:    store i32 0, ptr [[ADDR]], align 4344; CHECK-NEXT:    [[NEXT:%.*]] = icmp sgt i32 [[IDX_NEXT]], -1345; CHECK-NEXT:    br i1 [[NEXT]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]346; CHECK:       out.of.bounds.loopexit:347; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]348; CHECK:       out.of.bounds.loopexit1:349; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]350; CHECK:       out.of.bounds:351; CHECK-NEXT:    ret void352; CHECK:       exit.loopexit:353; CHECK-NEXT:    br label [[EXIT:%.*]]354; CHECK:       exit:355; CHECK-NEXT:    ret void356; CHECK:       loop.preloop:357; CHECK-NEXT:    [[IDX_PRELOOP:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP:%.*]], [[IN_BOUNDS_PRELOOP:%.*]] ], [ 100, [[LOOP_PRELOOP_PREHEADER]] ]358; CHECK-NEXT:    [[IDX_NEXT_PRELOOP]] = add i32 [[IDX_PRELOOP]], -7359; CHECK-NEXT:    [[ABC_PRELOOP:%.*]] = icmp slt i32 [[IDX_PRELOOP]], [[LEN]]360; CHECK-NEXT:    br i1 [[ABC_PRELOOP]], label [[IN_BOUNDS_PRELOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]361; CHECK:       in.bounds.preloop:362; CHECK-NEXT:    [[ADDR_PRELOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_PRELOOP]]363; CHECK-NEXT:    store i32 0, ptr [[ADDR_PRELOOP]], align 4364; CHECK-NEXT:    [[NEXT_PRELOOP:%.*]] = icmp sgt i32 [[IDX_NEXT_PRELOOP]], -1365; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[IDX_NEXT_PRELOOP]], [[EXIT_PRELOOP_AT]]366; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP12:![0-9]+]], !loop_constrainer.loop.clone !6367; CHECK:       preloop.exit.selector:368; CHECK-NEXT:    [[IDX_NEXT_PRELOOP_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP]], [[IN_BOUNDS_PRELOOP]] ]369; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[IDX_NEXT_PRELOOP_LCSSA]], -1370; CHECK-NEXT:    br i1 [[TMP2]], label [[PRELOOP_PSEUDO_EXIT]], label [[EXIT]]371; CHECK:       preloop.pseudo.exit:372; CHECK-NEXT:    [[IDX_PRELOOP_COPY]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]373; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 100, [[ENTRY]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]374; CHECK-NEXT:    br label [[MAINLOOP]]375;376 377entry:378  %len = load i32, ptr %a_len_ptr, !range !0379  br label %loop380 381loop:382  %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]383  %idx.next = add i32 %idx, -7384  %abc = icmp slt i32 %idx, %len385  br i1 %abc, label %in.bounds, label %out.of.bounds386 387in.bounds:388  %addr = getelementptr i32, ptr %arr, i32 %idx389  store i32 0, ptr %addr390  %next = icmp sgt i32 %idx.next, -1391  br i1 %next, label %loop, label %exit392 393out.of.bounds:394  ret void395 396exit:397  ret void398}399 400; IV = MAX_INT - 7; IV >u 6; IV -= 7; 10 <= Len <= 50. IRCE is allowed.401define void @test_06(ptr %arr, ptr %a_len_ptr) {402; CHECK-LABEL: define void @test_06403; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {404; CHECK-NEXT:  entry:405; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG13:![0-9]+]]406; CHECK-NEXT:    [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[LEN]], -1407; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 2147483640, [[EXIT_PRELOOP_AT]]408; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]409; CHECK:       loop.preloop.preheader:410; CHECK-NEXT:    br label [[LOOP_PRELOOP:%.*]]411; CHECK:       mainloop:412; CHECK-NEXT:    br label [[LOOP:%.*]]413; CHECK:       loop:414; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_PRELOOP_COPY:%.*]], [[MAINLOOP:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]415; CHECK-NEXT:    [[IDX_NEXT]] = add i32 [[IDX]], -7416; CHECK-NEXT:    [[ABC:%.*]] = icmp slt i32 [[IDX]], [[LEN]]417; CHECK-NEXT:    br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]418; CHECK:       in.bounds:419; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]420; CHECK-NEXT:    store i32 0, ptr [[ADDR]], align 4421; CHECK-NEXT:    [[NEXT:%.*]] = icmp ugt i32 [[IDX_NEXT]], 6422; CHECK-NEXT:    br i1 [[NEXT]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]423; CHECK:       out.of.bounds.loopexit:424; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]425; CHECK:       out.of.bounds.loopexit1:426; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]427; CHECK:       out.of.bounds:428; CHECK-NEXT:    ret void429; CHECK:       exit.loopexit:430; CHECK-NEXT:    br label [[EXIT:%.*]]431; CHECK:       exit:432; CHECK-NEXT:    ret void433; CHECK:       loop.preloop:434; CHECK-NEXT:    [[IDX_PRELOOP:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP:%.*]], [[IN_BOUNDS_PRELOOP:%.*]] ], [ 2147483640, [[LOOP_PRELOOP_PREHEADER]] ]435; CHECK-NEXT:    [[IDX_NEXT_PRELOOP]] = add i32 [[IDX_PRELOOP]], -7436; CHECK-NEXT:    [[ABC_PRELOOP:%.*]] = icmp slt i32 [[IDX_PRELOOP]], [[LEN]]437; CHECK-NEXT:    br i1 [[ABC_PRELOOP]], label [[IN_BOUNDS_PRELOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]438; CHECK:       in.bounds.preloop:439; CHECK-NEXT:    [[ADDR_PRELOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_PRELOOP]]440; CHECK-NEXT:    store i32 0, ptr [[ADDR_PRELOOP]], align 4441; CHECK-NEXT:    [[NEXT_PRELOOP:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP]], 6442; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP]], [[EXIT_PRELOOP_AT]]443; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP14:![0-9]+]], !loop_constrainer.loop.clone !6444; CHECK:       preloop.exit.selector:445; CHECK-NEXT:    [[IDX_NEXT_PRELOOP_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP]], [[IN_BOUNDS_PRELOOP]] ]446; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP_LCSSA]], 6447; CHECK-NEXT:    br i1 [[TMP2]], label [[PRELOOP_PSEUDO_EXIT]], label [[EXIT]]448; CHECK:       preloop.pseudo.exit:449; CHECK-NEXT:    [[IDX_PRELOOP_COPY]] = phi i32 [ 2147483640, [[ENTRY:%.*]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]450; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 2147483640, [[ENTRY]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]451; CHECK-NEXT:    br label [[MAINLOOP]]452;453 454entry:455  %len = load i32, ptr %a_len_ptr, !range !3456  br label %loop457 458loop:459  %idx = phi i32 [ 2147483640, %entry ], [ %idx.next, %in.bounds ]460  %idx.next = add i32 %idx, -7461  %abc = icmp slt i32 %idx, %len462  br i1 %abc, label %in.bounds, label %out.of.bounds463 464in.bounds:465  %addr = getelementptr i32, ptr %arr, i32 %idx466  store i32 0, ptr %addr467  %next = icmp ugt i32 %idx.next, 6468  br i1 %next, label %loop, label %exit469 470out.of.bounds:471  ret void472 473exit:474  ret void475}476 477; IV = MAX_INT - 7; IV >u 5; IV -= 7; 10 <= Len <= 50. IRCE is not allowed,478; because we can cross the 0 border.479define void @test_07(ptr %arr, ptr %a_len_ptr) {480; CHECK-LABEL: define void @test_07481; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {482; CHECK-NEXT:  entry:483; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG13]]484; CHECK-NEXT:    br label [[LOOP:%.*]]485; CHECK:       loop:486; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ 2147483640, [[ENTRY:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]487; CHECK-NEXT:    [[IDX_NEXT]] = add i32 [[IDX]], -7488; CHECK-NEXT:    [[ABC:%.*]] = icmp slt i32 [[IDX]], [[LEN]]489; CHECK-NEXT:    br i1 [[ABC]], label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS:%.*]]490; CHECK:       in.bounds:491; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]492; CHECK-NEXT:    store i32 0, ptr [[ADDR]], align 4493; CHECK-NEXT:    [[NEXT:%.*]] = icmp ugt i32 [[IDX_NEXT]], 5494; CHECK-NEXT:    br i1 [[NEXT]], label [[LOOP]], label [[EXIT:%.*]]495; CHECK:       out.of.bounds:496; CHECK-NEXT:    ret void497; CHECK:       exit:498; CHECK-NEXT:    ret void499;500 501entry:502  %len = load i32, ptr %a_len_ptr, !range !3503  br label %loop504 505loop:506  %idx = phi i32 [ 2147483640, %entry ], [ %idx.next, %in.bounds ]507  %idx.next = add i32 %idx, -7508  %abc = icmp slt i32 %idx, %len509  br i1 %abc, label %in.bounds, label %out.of.bounds510 511in.bounds:512  %addr = getelementptr i32, ptr %arr, i32 %idx513  store i32 0, ptr %addr514  %next = icmp ugt i32 %idx.next, 5515  br i1 %next, label %loop, label %exit516 517out.of.bounds:518  ret void519 520exit:521  ret void522}523 524; IV = MAX_INT; IV >u 6; IV -= 7; 10 <= Len <= 50. IRCE is allowed.525define void @test_08(ptr %arr, ptr %a_len_ptr) {526; CHECK-LABEL: define void @test_08527; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {528; CHECK-NEXT:  entry:529; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG13]]530; CHECK-NEXT:    [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[LEN]], -1531; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 2147483647, [[EXIT_PRELOOP_AT]]532; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]533; CHECK:       loop.preloop.preheader:534; CHECK-NEXT:    br label [[LOOP_PRELOOP:%.*]]535; CHECK:       mainloop:536; CHECK-NEXT:    br label [[LOOP:%.*]]537; CHECK:       loop:538; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_PRELOOP_COPY:%.*]], [[MAINLOOP:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]539; CHECK-NEXT:    [[IDX_NEXT]] = add i32 [[IDX]], -7540; CHECK-NEXT:    [[ABC:%.*]] = icmp slt i32 [[IDX]], [[LEN]]541; CHECK-NEXT:    br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]542; CHECK:       in.bounds:543; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]544; CHECK-NEXT:    store i32 0, ptr [[ADDR]], align 4545; CHECK-NEXT:    [[NEXT:%.*]] = icmp ugt i32 [[IDX_NEXT]], 6546; CHECK-NEXT:    br i1 [[NEXT]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]547; CHECK:       out.of.bounds.loopexit:548; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]549; CHECK:       out.of.bounds.loopexit1:550; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]551; CHECK:       out.of.bounds:552; CHECK-NEXT:    ret void553; CHECK:       exit.loopexit:554; CHECK-NEXT:    br label [[EXIT:%.*]]555; CHECK:       exit:556; CHECK-NEXT:    ret void557; CHECK:       loop.preloop:558; CHECK-NEXT:    [[IDX_PRELOOP:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP:%.*]], [[IN_BOUNDS_PRELOOP:%.*]] ], [ 2147483647, [[LOOP_PRELOOP_PREHEADER]] ]559; CHECK-NEXT:    [[IDX_NEXT_PRELOOP]] = add i32 [[IDX_PRELOOP]], -7560; CHECK-NEXT:    [[ABC_PRELOOP:%.*]] = icmp slt i32 [[IDX_PRELOOP]], [[LEN]]561; CHECK-NEXT:    br i1 [[ABC_PRELOOP]], label [[IN_BOUNDS_PRELOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]562; CHECK:       in.bounds.preloop:563; CHECK-NEXT:    [[ADDR_PRELOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_PRELOOP]]564; CHECK-NEXT:    store i32 0, ptr [[ADDR_PRELOOP]], align 4565; CHECK-NEXT:    [[NEXT_PRELOOP:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP]], 6566; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP]], [[EXIT_PRELOOP_AT]]567; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP15:![0-9]+]], !loop_constrainer.loop.clone !6568; CHECK:       preloop.exit.selector:569; CHECK-NEXT:    [[IDX_NEXT_PRELOOP_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP]], [[IN_BOUNDS_PRELOOP]] ]570; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP_LCSSA]], 6571; CHECK-NEXT:    br i1 [[TMP2]], label [[PRELOOP_PSEUDO_EXIT]], label [[EXIT]]572; CHECK:       preloop.pseudo.exit:573; CHECK-NEXT:    [[IDX_PRELOOP_COPY]] = phi i32 [ 2147483647, [[ENTRY:%.*]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]574; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 2147483647, [[ENTRY]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]575; CHECK-NEXT:    br label [[MAINLOOP]]576;577 578entry:579  %len = load i32, ptr %a_len_ptr, !range !3580  br label %loop581 582loop:583  %idx = phi i32 [ 2147483647, %entry ], [ %idx.next, %in.bounds ]584  %idx.next = add i32 %idx, -7585  %abc = icmp slt i32 %idx, %len586  br i1 %abc, label %in.bounds, label %out.of.bounds587 588in.bounds:589  %addr = getelementptr i32, ptr %arr, i32 %idx590  store i32 0, ptr %addr591  %next = icmp ugt i32 %idx.next, 6592  br i1 %next, label %loop, label %exit593 594out.of.bounds:595  ret void596 597exit:598  ret void599}600 601; IRCE is legal here.602; Here how it is done if the step was 1: https://godbolt.org/z/jEqWaseWc603; It is also legal for step 4. Proof:604; - Capacity check ensures that iv < limit <= SINT_MAX - 3, meaning that605;   iv <= SINT_MAX - 4.606; - Because of this, iv.next is always computed w/o overflow.607; - The loop goes to backedge as long as iv < capacity - 3 && iv < num.elements - 4.608; - So iterating up to smin(capacity - 3, num.elements - 4) should be safe.609; - Proof by alive2: https://alive2.llvm.org/ce/z/vEhMxa610define i32 @test_09(ptr %p, ptr %capacity_p, ptr %num_elements_p) {611; CHECK-LABEL: define i32 @test_09612; CHECK-SAME: (ptr [[P:%.*]], ptr [[CAPACITY_P:%.*]], ptr [[NUM_ELEMENTS_P:%.*]]) {613; CHECK-NEXT:  entry:614; CHECK-NEXT:    [[CAPACITY:%.*]] = load i32, ptr [[CAPACITY_P]], align 4, !range [[RNG16:![0-9]+]]615; CHECK-NEXT:    [[NUM_ELEMENTS:%.*]] = load i32, ptr [[NUM_ELEMENTS_P]], align 4, !range [[RNG16]]616; CHECK-NEXT:    [[LIMIT:%.*]] = sub i32 [[CAPACITY]], 3617; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[CAPACITY]], -3618; CHECK-NEXT:    [[TMP1:%.*]] = add nuw i32 [[CAPACITY]], 2147483646619; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP1]], i32 0)620; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 [[TMP0]], [[SMAX]]621; CHECK-NEXT:    [[SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[LIMIT]], i32 0)622; CHECK-NEXT:    [[SMAX2:%.*]] = call i32 @llvm.smax.i32(i32 [[SMIN]], i32 -1)623; CHECK-NEXT:    [[TMP3:%.*]] = add nsw i32 [[SMAX2]], 1624; CHECK-NEXT:    [[TMP4:%.*]] = mul i32 [[TMP2]], [[TMP3]]625; CHECK-NEXT:    [[SMIN3:%.*]] = call i32 @llvm.smin.i32(i32 [[NUM_ELEMENTS]], i32 [[TMP4]])626; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.smax.i32(i32 [[SMIN3]], i32 0)627; CHECK-NEXT:    [[TMP5:%.*]] = icmp slt i32 0, [[EXIT_MAINLOOP_AT]]628; CHECK-NEXT:    br i1 [[TMP5]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]629; CHECK:       loop.preheader:630; CHECK-NEXT:    br label [[LOOP:%.*]]631; CHECK:       loop:632; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]633; CHECK-NEXT:    [[CAPACITY_CHECK:%.*]] = icmp slt i32 [[IV]], [[LIMIT]]634; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[OUT_OF_BOUNDS_LOOPEXIT5:%.*]], !prof [[PROF17:![0-9]+]]635; CHECK:       backedge:636; CHECK-NEXT:    [[IV_WIDE:%.*]] = zext i32 [[IV]] to i64637; CHECK-NEXT:    [[EL_PTR:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV_WIDE]]638; CHECK-NEXT:    store i32 1, ptr [[EL_PTR]], align 4639; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 4640; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[NUM_ELEMENTS]]641; CHECK-NEXT:    [[TMP6:%.*]] = icmp slt i32 [[IV_NEXT]], [[EXIT_MAINLOOP_AT]]642; CHECK-NEXT:    br i1 [[TMP6]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]643; CHECK:       main.exit.selector:644; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[BACKEDGE]] ]645; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[BACKEDGE]] ]646; CHECK-NEXT:    [[TMP7:%.*]] = icmp slt i32 [[IV_NEXT_LCSSA]], [[NUM_ELEMENTS]]647; CHECK-NEXT:    br i1 [[TMP7]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]648; CHECK:       main.pseudo.exit:649; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]650; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]651; CHECK-NEXT:    br label [[POSTLOOP:%.*]]652; CHECK:       exit.loopexit:653; CHECK-NEXT:    [[IV_LCSSA1_PH:%.*]] = phi i32 [ [[IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]654; CHECK-NEXT:    br label [[EXIT]]655; CHECK:       exit:656; CHECK-NEXT:    [[IV_LCSSA1:%.*]] = phi i32 [ [[IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ], [ [[IV_LCSSA1_PH]], [[EXIT_LOOPEXIT:%.*]] ]657; CHECK-NEXT:    ret i32 [[IV_LCSSA1]]658; CHECK:       out_of_bounds.loopexit:659; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]660; CHECK:       out_of_bounds.loopexit5:661; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]662; CHECK:       out_of_bounds:663; CHECK-NEXT:    ret i32 -1664; CHECK:       postloop:665; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]666; CHECK:       loop.postloop:667; CHECK-NEXT:    [[IV_POSTLOOP]] = phi i32 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]668; CHECK-NEXT:    [[CAPACITY_CHECK_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], [[LIMIT]]669; CHECK-NEXT:    br i1 [[CAPACITY_CHECK_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]], !prof [[PROF17]]670; CHECK:       backedge.postloop:671; CHECK-NEXT:    [[IV_WIDE_POSTLOOP:%.*]] = zext i32 [[IV_POSTLOOP]] to i64672; CHECK-NEXT:    [[EL_PTR_POSTLOOP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV_WIDE_POSTLOOP]]673; CHECK-NEXT:    store i32 1, ptr [[EL_PTR_POSTLOOP]], align 4674; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add nuw nsw i32 [[IV_POSTLOOP]], 4675; CHECK-NEXT:    [[LOOP_COND_POSTLOOP:%.*]] = icmp slt i32 [[IV_NEXT_POSTLOOP]], [[NUM_ELEMENTS]]676; CHECK-NEXT:    br i1 [[LOOP_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP18:![0-9]+]], !loop_constrainer.loop.clone !6677;678entry:679  %capacity = load i32, ptr %capacity_p, !range !4680  %num_elements = load i32, ptr %num_elements_p, !range !4681  %limit = sub i32 %capacity, 3682  br label %loop683 684loop:685  %iv = phi i32 [0, %entry], [%iv.next, %backedge]686  %capacity_check = icmp slt i32 %iv, %limit687  br i1 %capacity_check, label %backedge, label %out_of_bounds, !prof !5688 689backedge:690  %iv.wide = zext i32 %iv to i64691  %el.ptr = getelementptr i32, ptr %p, i64 %iv.wide692  store i32 1, ptr %el.ptr693  %iv.next = add nuw nsw i32 %iv, 4694  %loop_cond = icmp slt i32 %iv.next, %num_elements695  br i1 %loop_cond, label %loop, label %exit696 697exit:698  ret i32 %iv699 700out_of_bounds:701  ret i32 -1702}703 704; Same as test_09 but range check comparison is inversed.705; IRCE is allowed.706define i32 @test_10(ptr %p, ptr %capacity_p, ptr %num_elements_p) {707; CHECK-LABEL: define i32 @test_10708; CHECK-SAME: (ptr [[P:%.*]], ptr [[CAPACITY_P:%.*]], ptr [[NUM_ELEMENTS_P:%.*]]) {709; CHECK-NEXT:  entry:710; CHECK-NEXT:    [[CAPACITY:%.*]] = load i32, ptr [[CAPACITY_P]], align 4, !range [[RNG16]]711; CHECK-NEXT:    [[NUM_ELEMENTS:%.*]] = load i32, ptr [[NUM_ELEMENTS_P]], align 4, !range [[RNG16]]712; CHECK-NEXT:    [[LIMIT:%.*]] = sub i32 [[CAPACITY]], 3713; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[CAPACITY]], -3714; CHECK-NEXT:    [[TMP1:%.*]] = add nuw i32 [[CAPACITY]], 2147483646715; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP1]], i32 0)716; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 [[TMP0]], [[SMAX]]717; CHECK-NEXT:    [[SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[LIMIT]], i32 0)718; CHECK-NEXT:    [[SMAX2:%.*]] = call i32 @llvm.smax.i32(i32 [[SMIN]], i32 -1)719; CHECK-NEXT:    [[TMP3:%.*]] = add nsw i32 [[SMAX2]], 1720; CHECK-NEXT:    [[TMP4:%.*]] = mul i32 [[TMP2]], [[TMP3]]721; CHECK-NEXT:    [[SMIN3:%.*]] = call i32 @llvm.smin.i32(i32 [[NUM_ELEMENTS]], i32 [[TMP4]])722; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.smax.i32(i32 [[SMIN3]], i32 0)723; CHECK-NEXT:    [[TMP5:%.*]] = icmp slt i32 0, [[EXIT_MAINLOOP_AT]]724; CHECK-NEXT:    br i1 [[TMP5]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]725; CHECK:       loop.preheader:726; CHECK-NEXT:    br label [[LOOP:%.*]]727; CHECK:       loop:728; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]729; CHECK-NEXT:    [[CAPACITY_CHECK:%.*]] = icmp slt i32 [[IV]], [[LIMIT]]730; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[OUT_OF_BOUNDS_LOOPEXIT5:%.*]], !prof [[PROF17]]731; CHECK:       backedge:732; CHECK-NEXT:    [[IV_WIDE:%.*]] = zext i32 [[IV]] to i64733; CHECK-NEXT:    [[EL_PTR:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV_WIDE]]734; CHECK-NEXT:    store i32 1, ptr [[EL_PTR]], align 4735; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 4736; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[NUM_ELEMENTS]]737; CHECK-NEXT:    [[TMP6:%.*]] = icmp slt i32 [[IV_NEXT]], [[EXIT_MAINLOOP_AT]]738; CHECK-NEXT:    br i1 [[TMP6]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]739; CHECK:       main.exit.selector:740; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[BACKEDGE]] ]741; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[BACKEDGE]] ]742; CHECK-NEXT:    [[TMP7:%.*]] = icmp slt i32 [[IV_NEXT_LCSSA]], [[NUM_ELEMENTS]]743; CHECK-NEXT:    br i1 [[TMP7]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]744; CHECK:       main.pseudo.exit:745; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]746; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]747; CHECK-NEXT:    br label [[POSTLOOP:%.*]]748; CHECK:       exit.loopexit:749; CHECK-NEXT:    [[IV_LCSSA1_PH:%.*]] = phi i32 [ [[IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]750; CHECK-NEXT:    br label [[EXIT]]751; CHECK:       exit:752; CHECK-NEXT:    [[IV_LCSSA1:%.*]] = phi i32 [ [[IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ], [ [[IV_LCSSA1_PH]], [[EXIT_LOOPEXIT:%.*]] ]753; CHECK-NEXT:    ret i32 [[IV_LCSSA1]]754; CHECK:       out_of_bounds.loopexit:755; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]756; CHECK:       out_of_bounds.loopexit5:757; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]758; CHECK:       out_of_bounds:759; CHECK-NEXT:    ret i32 -1760; CHECK:       postloop:761; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]762; CHECK:       loop.postloop:763; CHECK-NEXT:    [[IV_POSTLOOP]] = phi i32 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]764; CHECK-NEXT:    [[CAPACITY_CHECK_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], [[LIMIT]]765; CHECK-NEXT:    br i1 [[CAPACITY_CHECK_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]], !prof [[PROF17]]766; CHECK:       backedge.postloop:767; CHECK-NEXT:    [[IV_WIDE_POSTLOOP:%.*]] = zext i32 [[IV_POSTLOOP]] to i64768; CHECK-NEXT:    [[EL_PTR_POSTLOOP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV_WIDE_POSTLOOP]]769; CHECK-NEXT:    store i32 1, ptr [[EL_PTR_POSTLOOP]], align 4770; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add nuw nsw i32 [[IV_POSTLOOP]], 4771; CHECK-NEXT:    [[LOOP_COND_POSTLOOP:%.*]] = icmp slt i32 [[IV_NEXT_POSTLOOP]], [[NUM_ELEMENTS]]772; CHECK-NEXT:    br i1 [[LOOP_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP19:![0-9]+]], !loop_constrainer.loop.clone !6773;774entry:775  %capacity = load i32, ptr %capacity_p, !range !4776  %num_elements = load i32, ptr %num_elements_p, !range !4777  %limit = sub i32 %capacity, 3778  br label %loop779 780loop:781  %iv = phi i32 [0, %entry], [%iv.next, %backedge]782  %capacity_check = icmp sge i32 %iv, %limit783  br i1 %capacity_check, label %out_of_bounds, label %backedge, !prof !6784 785backedge:786  %iv.wide = zext i32 %iv to i64787  %el.ptr = getelementptr i32, ptr %p, i64 %iv.wide788  store i32 1, ptr %el.ptr789  %iv.next = add nuw nsw i32 %iv, 4790  %loop_cond = icmp slt i32 %iv.next, %num_elements791  br i1 %loop_cond, label %loop, label %exit792 793exit:794  ret i32 %iv795 796out_of_bounds:797  ret i32 -1798}799 800; Same as test_09 but range check comparison is non-strict:801; IRCE is allowed.802define i32 @test_11(ptr %p, ptr %capacity_p, ptr %num_elements_p) {803; CHECK-LABEL: define i32 @test_11804; CHECK-SAME: (ptr [[P:%.*]], ptr [[CAPACITY_P:%.*]], ptr [[NUM_ELEMENTS_P:%.*]]) {805; CHECK-NEXT:  entry:806; CHECK-NEXT:    [[CAPACITY:%.*]] = load i32, ptr [[CAPACITY_P]], align 4, !range [[RNG16]]807; CHECK-NEXT:    [[NUM_ELEMENTS:%.*]] = load i32, ptr [[NUM_ELEMENTS_P]], align 4, !range [[RNG16]]808; CHECK-NEXT:    [[LIMIT:%.*]] = sub i32 [[CAPACITY]], 4809; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[CAPACITY]], -3810; CHECK-NEXT:    [[TMP1:%.*]] = add nuw i32 [[CAPACITY]], 2147483646811; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP1]], i32 0)812; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 [[TMP0]], [[SMAX]]813; CHECK-NEXT:    [[TMP3:%.*]] = add nsw i32 [[CAPACITY]], -3814; CHECK-NEXT:    [[SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP3]], i32 0)815; CHECK-NEXT:    [[SMAX2:%.*]] = call i32 @llvm.smax.i32(i32 [[SMIN]], i32 -1)816; CHECK-NEXT:    [[TMP4:%.*]] = add nsw i32 [[SMAX2]], 1817; CHECK-NEXT:    [[TMP5:%.*]] = mul i32 [[TMP2]], [[TMP4]]818; CHECK-NEXT:    [[SMIN3:%.*]] = call i32 @llvm.smin.i32(i32 [[NUM_ELEMENTS]], i32 [[TMP5]])819; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.smax.i32(i32 [[SMIN3]], i32 0)820; CHECK-NEXT:    [[TMP6:%.*]] = icmp slt i32 0, [[EXIT_MAINLOOP_AT]]821; CHECK-NEXT:    br i1 [[TMP6]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]822; CHECK:       loop.preheader:823; CHECK-NEXT:    br label [[LOOP:%.*]]824; CHECK:       loop:825; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]826; CHECK-NEXT:    [[CAPACITY_CHECK:%.*]] = icmp sle i32 [[IV]], [[LIMIT]]827; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[OUT_OF_BOUNDS_LOOPEXIT5:%.*]], !prof [[PROF17]]828; CHECK:       backedge:829; CHECK-NEXT:    [[IV_WIDE:%.*]] = zext i32 [[IV]] to i64830; CHECK-NEXT:    [[EL_PTR:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV_WIDE]]831; CHECK-NEXT:    store i32 1, ptr [[EL_PTR]], align 4832; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 4833; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[NUM_ELEMENTS]]834; CHECK-NEXT:    [[TMP7:%.*]] = icmp slt i32 [[IV_NEXT]], [[EXIT_MAINLOOP_AT]]835; CHECK-NEXT:    br i1 [[TMP7]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]836; CHECK:       main.exit.selector:837; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i32 [ [[IV_NEXT]], [[BACKEDGE]] ]838; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[BACKEDGE]] ]839; CHECK-NEXT:    [[TMP8:%.*]] = icmp slt i32 [[IV_NEXT_LCSSA]], [[NUM_ELEMENTS]]840; CHECK-NEXT:    br i1 [[TMP8]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]841; CHECK:       main.pseudo.exit:842; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]843; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]844; CHECK-NEXT:    br label [[POSTLOOP:%.*]]845; CHECK:       exit.loopexit:846; CHECK-NEXT:    [[IV_LCSSA1_PH:%.*]] = phi i32 [ [[IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]847; CHECK-NEXT:    br label [[EXIT]]848; CHECK:       exit:849; CHECK-NEXT:    [[IV_LCSSA1:%.*]] = phi i32 [ [[IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ], [ [[IV_LCSSA1_PH]], [[EXIT_LOOPEXIT:%.*]] ]850; CHECK-NEXT:    ret i32 [[IV_LCSSA1]]851; CHECK:       out_of_bounds.loopexit:852; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]853; CHECK:       out_of_bounds.loopexit5:854; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]855; CHECK:       out_of_bounds:856; CHECK-NEXT:    ret i32 -1857; CHECK:       postloop:858; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]859; CHECK:       loop.postloop:860; CHECK-NEXT:    [[IV_POSTLOOP]] = phi i32 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]861; CHECK-NEXT:    [[CAPACITY_CHECK_POSTLOOP:%.*]] = icmp sle i32 [[IV_POSTLOOP]], [[LIMIT]]862; CHECK-NEXT:    br i1 [[CAPACITY_CHECK_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]], !prof [[PROF17]]863; CHECK:       backedge.postloop:864; CHECK-NEXT:    [[IV_WIDE_POSTLOOP:%.*]] = zext i32 [[IV_POSTLOOP]] to i64865; CHECK-NEXT:    [[EL_PTR_POSTLOOP:%.*]] = getelementptr i32, ptr [[P]], i64 [[IV_WIDE_POSTLOOP]]866; CHECK-NEXT:    store i32 1, ptr [[EL_PTR_POSTLOOP]], align 4867; CHECK-NEXT:    [[IV_NEXT_POSTLOOP]] = add nuw nsw i32 [[IV_POSTLOOP]], 4868; CHECK-NEXT:    [[LOOP_COND_POSTLOOP:%.*]] = icmp slt i32 [[IV_NEXT_POSTLOOP]], [[NUM_ELEMENTS]]869; CHECK-NEXT:    br i1 [[LOOP_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP20:![0-9]+]], !loop_constrainer.loop.clone !6870;871entry:872  %capacity = load i32, ptr %capacity_p, !range !4873  %num_elements = load i32, ptr %num_elements_p, !range !4874  %limit = sub i32 %capacity, 4875  br label %loop876 877loop:878  %iv = phi i32 [0, %entry], [%iv.next, %backedge]879  %capacity_check = icmp sle i32 %iv, %limit880  br i1 %capacity_check, label %backedge, label %out_of_bounds, !prof !5881 882backedge:883  %iv.wide = zext i32 %iv to i64884  %el.ptr = getelementptr i32, ptr %p, i64 %iv.wide885  store i32 1, ptr %el.ptr886  %iv.next = add nuw nsw i32 %iv, 4887  %loop_cond = icmp slt i32 %iv.next, %num_elements888  br i1 %loop_cond, label %loop, label %exit889 890exit:891  ret i32 %iv892 893out_of_bounds:894  ret i32 -1895}896 897; Indvar base is non-overflowing binary 'or':898; check that IRCE isn't trying to add NSW flag on it.899define i32 @binop_or_is_iv_base(ptr %p, i32 %end) {900; CHECK-LABEL: define i32 @binop_or_is_iv_base901; CHECK-SAME: (ptr [[P:%.*]], i32 [[END:%.*]]) {902; CHECK-NEXT:  entry:903; CHECK-NEXT:    [[N:%.*]] = load atomic i32, ptr [[P]] unordered, align 8, !range [[RNG8]]904; CHECK-NEXT:    [[CMP0:%.*]] = icmp sgt i32 [[END]], 7905; CHECK-NEXT:    br i1 [[CMP0]], label [[LOOP_HEADER_PREHEADER:%.*]], label [[COMMON_RET:%.*]]906; CHECK:       loop.header.preheader:907; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[N]], 7908; CHECK-NEXT:    [[SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[END]], i32 [[TMP0]])909; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.smax.i32(i32 [[SMIN]], i32 7)910; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 7, [[EXIT_MAINLOOP_AT]]911; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_HEADER_PREHEADER1:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]912; CHECK:       loop.header.preheader1:913; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]914; CHECK:       loop.header:915; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_ADD:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_HEADER_PREHEADER1]] ]916; CHECK-NEXT:    [[CHECK:%.*]] = icmp ult i32 [[IV]], [[N]]917; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT_LOOPEXIT2:%.*]]918; CHECK:       guarded:919; CHECK-NEXT:    [[IV_ADD]] = add i32 [[IV]], 8920; CHECK-NEXT:    [[IV_OR:%.*]] = or disjoint i32 [[IV_ADD]], 7921; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[IV_OR]], [[END]]922; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[IV_OR]], [[EXIT_MAINLOOP_AT]]923; CHECK-NEXT:    br i1 [[TMP2]], label [[LOOP_HEADER]], label [[MAIN_EXIT_SELECTOR:%.*]]924; CHECK:       main.exit.selector:925; CHECK-NEXT:    [[IV_ADD_LCSSA:%.*]] = phi i32 [ [[IV_ADD]], [[GUARDED]] ]926; CHECK-NEXT:    [[IV_OR_LCSSA:%.*]] = phi i32 [ [[IV_OR]], [[GUARDED]] ]927; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[IV_OR_LCSSA]], [[END]]928; CHECK-NEXT:    br i1 [[TMP3]], label [[MAIN_PSEUDO_EXIT]], label [[COMMON_RET_LOOPEXIT:%.*]]929; CHECK:       main.pseudo.exit:930; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ 0, [[LOOP_HEADER_PREHEADER]] ], [ [[IV_ADD_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]931; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 7, [[LOOP_HEADER_PREHEADER]] ], [ [[IV_OR_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]932; CHECK-NEXT:    br label [[POSTLOOP:%.*]]933; CHECK:       deopt.loopexit:934; CHECK-NEXT:    br label [[DEOPT:%.*]]935; CHECK:       deopt.loopexit2:936; CHECK-NEXT:    br label [[DEOPT]]937; CHECK:       deopt:938; CHECK-NEXT:    [[RV:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 13) [ "deopt"() ]939; CHECK-NEXT:    ret i32 [[RV]]940; CHECK:       common.ret.loopexit.loopexit:941; CHECK-NEXT:    br label [[COMMON_RET_LOOPEXIT]]942; CHECK:       common.ret.loopexit:943; CHECK-NEXT:    br label [[COMMON_RET]]944; CHECK:       common.ret:945; CHECK-NEXT:    ret i32 [[END]]946; CHECK:       postloop:947; CHECK-NEXT:    br label [[LOOP_HEADER_POSTLOOP:%.*]]948; CHECK:       loop.header.postloop:949; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i32 [ [[IV_ADD_POSTLOOP:%.*]], [[GUARDED_POSTLOOP:%.*]] ], [ [[IV_COPY]], [[POSTLOOP]] ]950; CHECK-NEXT:    [[CHECK_POSTLOOP:%.*]] = icmp ult i32 [[IV_POSTLOOP]], [[N]]951; CHECK-NEXT:    br i1 [[CHECK_POSTLOOP]], label [[GUARDED_POSTLOOP]], label [[DEOPT_LOOPEXIT:%.*]]952; CHECK:       guarded.postloop:953; CHECK-NEXT:    [[IV_ADD_POSTLOOP]] = add i32 [[IV_POSTLOOP]], 8954; CHECK-NEXT:    [[IV_OR_POSTLOOP:%.*]] = or disjoint i32 [[IV_ADD_POSTLOOP]], 7955; CHECK-NEXT:    [[CMP_POSTLOOP:%.*]] = icmp slt i32 [[IV_OR_POSTLOOP]], [[END]]956; CHECK-NEXT:    br i1 [[CMP_POSTLOOP]], label [[LOOP_HEADER_POSTLOOP]], label [[COMMON_RET_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP21:![0-9]+]], !loop_constrainer.loop.clone !6957;958entry:959  %n = load atomic i32, ptr %p unordered, align 8, !range !1960  %cmp0 = icmp sgt i32 %end, 7961  br i1 %cmp0, label %loop.header, label %common.ret962 963loop.header:964  %iv = phi i32 [ %iv.add, %guarded ], [ 0, %entry ]965  %check = icmp ult i32 %iv, %n966  br i1 %check, label %guarded, label %deopt967 968guarded:969  %iv.add = add i32 %iv, 8970  %iv.or = or disjoint i32 %iv.add, 7971  %cmp = icmp slt i32 %iv.or, %end972  br i1 %cmp, label %loop.header, label %common.ret973 974deopt:975  %rv = call i32 (...) @llvm.experimental.deoptimize.i32(i32 13) [ "deopt"() ]976  ret i32 %rv977 978common.ret:979  ret i32 %end980}981 982declare i32 @llvm.experimental.deoptimize.i32(...)983 984!0 = !{i32 0, i32 50}985!1 = !{i32 0, i32 2147483640}986!2 = !{i32 0, i32 2147483641}987!3 = !{i32 10, i32 50}988!4 = !{i32 1, i32 2147483648}989!5 = !{!"branch_weights", i32 1000, i32 1}990!6 = !{!"branch_weights", i32 1, i32 1000}991