666 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: 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; CHECK-NOT: irce: in function test_09: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>14 15; ULT condition for increasing loop.16define void @test_01(ptr %arr, ptr %a_len_ptr) #0 {17; CHECK-LABEL: define void @test_0118; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {19; CHECK-NEXT: entry:20; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0:![0-9]+]]21; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]22; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]23; CHECK: loop.preheader:24; CHECK-NEXT: br label [[LOOP:%.*]]25; CHECK: loop:26; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]27; CHECK-NEXT: [[IDX_NEXT]] = add nuw nsw i32 [[IDX]], 128; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[EXIT_MAINLOOP_AT]]29; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]30; CHECK: in.bounds:31; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]32; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 433; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], 10034; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]35; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]36; CHECK: main.exit.selector:37; CHECK-NEXT: [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]38; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[IDX_NEXT_LCSSA]], 10039; CHECK-NEXT: br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]40; CHECK: main.pseudo.exit:41; CHECK-NEXT: [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]42; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]43; CHECK-NEXT: br label [[POSTLOOP:%.*]]44; CHECK: out.of.bounds.loopexit:45; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]]46; CHECK: out.of.bounds.loopexit1:47; CHECK-NEXT: br label [[OUT_OF_BOUNDS]]48; CHECK: out.of.bounds:49; CHECK-NEXT: ret void50; CHECK: exit.loopexit:51; CHECK-NEXT: br label [[EXIT]]52; CHECK: exit:53; CHECK-NEXT: ret void54; CHECK: postloop:55; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]56; CHECK: loop.postloop:57; CHECK-NEXT: [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]58; CHECK-NEXT: [[IDX_NEXT_POSTLOOP]] = add nuw nsw i32 [[IDX_POSTLOOP]], 159; CHECK-NEXT: [[ABC_POSTLOOP:%.*]] = icmp ult i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]60; CHECK-NEXT: br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]61; CHECK: in.bounds.postloop:62; CHECK-NEXT: [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]63; CHECK-NEXT: store i32 0, ptr [[ADDR_POSTLOOP]], align 464; CHECK-NEXT: [[NEXT_POSTLOOP:%.*]] = icmp ult i32 [[IDX_NEXT_POSTLOOP]], 10065; CHECK-NEXT: br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP1:![0-9]+]], !loop_constrainer.loop.clone [[META6:![0-9]+]]66;67 68entry:69 %len = load i32, ptr %a_len_ptr, !range !070 br label %loop71 72loop:73 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]74 %idx.next = add nsw nuw i32 %idx, 175 %abc = icmp ult i32 %idx, %len76 br i1 %abc, label %in.bounds, label %out.of.bounds77 78in.bounds:79 %addr = getelementptr i32, ptr %arr, i32 %idx80 store i32 0, ptr %addr81 %next = icmp ult i32 %idx.next, 10082 br i1 %next, label %loop, label %exit83 84out.of.bounds:85 ret void86 87exit:88 ret void89}90 91; ULT condition for decreasing loops.92define void @test_02(ptr %arr, ptr %a_len_ptr) #0 {93; CHECK-LABEL: define void @test_0294; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {95; CHECK-NEXT: entry:96; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]97; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[LEN]], i32 1)98; CHECK-NEXT: [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[UMAX]], -199; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 100, [[EXIT_PRELOOP_AT]]100; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]101; CHECK: loop.preloop.preheader:102; CHECK-NEXT: br label [[LOOP_PRELOOP:%.*]]103; CHECK: mainloop:104; CHECK-NEXT: br label [[LOOP:%.*]]105; CHECK: loop:106; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_PRELOOP_COPY:%.*]], [[MAINLOOP:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]107; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], -1108; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[LEN]]109; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]110; CHECK: in.bounds:111; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]112; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4113; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], 1114; CHECK-NEXT: br i1 [[NEXT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]]115; CHECK: out.of.bounds.loopexit:116; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]]117; CHECK: out.of.bounds.loopexit1:118; CHECK-NEXT: br label [[OUT_OF_BOUNDS]]119; CHECK: out.of.bounds:120; CHECK-NEXT: ret void121; CHECK: exit.loopexit:122; CHECK-NEXT: br label [[EXIT:%.*]]123; CHECK: exit:124; CHECK-NEXT: ret void125; CHECK: loop.preloop:126; CHECK-NEXT: [[IDX_PRELOOP:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP:%.*]], [[IN_BOUNDS_PRELOOP:%.*]] ], [ 100, [[LOOP_PRELOOP_PREHEADER]] ]127; CHECK-NEXT: [[IDX_NEXT_PRELOOP]] = add i32 [[IDX_PRELOOP]], -1128; CHECK-NEXT: [[ABC_PRELOOP:%.*]] = icmp ult i32 [[IDX_PRELOOP]], [[LEN]]129; CHECK-NEXT: br i1 [[ABC_PRELOOP]], label [[IN_BOUNDS_PRELOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]130; CHECK: in.bounds.preloop:131; CHECK-NEXT: [[ADDR_PRELOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_PRELOOP]]132; CHECK-NEXT: store i32 0, ptr [[ADDR_PRELOOP]], align 4133; CHECK-NEXT: [[NEXT_PRELOOP:%.*]] = icmp ult i32 [[IDX_NEXT_PRELOOP]], 1134; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP]], [[EXIT_PRELOOP_AT]]135; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true136; CHECK-NEXT: br i1 [[TMP2]], label [[PRELOOP_EXIT_SELECTOR:%.*]], label [[LOOP_PRELOOP]], !llvm.loop [[LOOP7:![0-9]+]], !loop_constrainer.loop.clone [[META6]]137; CHECK: preloop.exit.selector:138; CHECK-NEXT: [[IDX_NEXT_PRELOOP_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP]], [[IN_BOUNDS_PRELOOP]] ]139; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP_LCSSA]], 0140; CHECK-NEXT: br i1 [[TMP3]], label [[PRELOOP_PSEUDO_EXIT]], label [[EXIT]]141; CHECK: preloop.pseudo.exit:142; CHECK-NEXT: [[IDX_PRELOOP_COPY]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]143; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 100, [[ENTRY]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]144; CHECK-NEXT: br label [[MAINLOOP]]145;146 147entry:148 %len = load i32, ptr %a_len_ptr, !range !0149 br label %loop150 151loop:152 %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]153 %idx.next = add i32 %idx, -1154 %abc = icmp ult i32 %idx, %len155 br i1 %abc, label %in.bounds, label %out.of.bounds156 157in.bounds:158 %addr = getelementptr i32, ptr %arr, i32 %idx159 store i32 0, ptr %addr160 %next = icmp ult i32 %idx.next, 1161 br i1 %next, label %exit, label %loop162 163out.of.bounds:164 ret void165 166exit:167 ret void168}169 170; Check SINT_MAX.171define void @test_03(ptr %arr, ptr %a_len_ptr) #0 {172; CHECK-LABEL: define void @test_03173; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {174; CHECK-NEXT: entry:175; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]176; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]177; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]178; CHECK: loop.preheader:179; CHECK-NEXT: br label [[LOOP:%.*]]180; CHECK: loop:181; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]182; CHECK-NEXT: [[IDX_NEXT]] = add nuw nsw i32 [[IDX]], 1183; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[EXIT_MAINLOOP_AT]]184; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]185; CHECK: in.bounds:186; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]187; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4188; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], 2147483647189; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]190; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]191; CHECK: main.exit.selector:192; CHECK-NEXT: [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]193; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[IDX_NEXT_LCSSA]], 2147483647194; CHECK-NEXT: br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]195; CHECK: main.pseudo.exit:196; CHECK-NEXT: [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]197; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]198; CHECK-NEXT: br label [[POSTLOOP:%.*]]199; CHECK: out.of.bounds.loopexit:200; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]]201; CHECK: out.of.bounds.loopexit1:202; CHECK-NEXT: br label [[OUT_OF_BOUNDS]]203; CHECK: out.of.bounds:204; CHECK-NEXT: ret void205; CHECK: exit.loopexit:206; CHECK-NEXT: br label [[EXIT]]207; CHECK: exit:208; CHECK-NEXT: ret void209; CHECK: postloop:210; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]211; CHECK: loop.postloop:212; CHECK-NEXT: [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]213; CHECK-NEXT: [[IDX_NEXT_POSTLOOP]] = add nuw nsw i32 [[IDX_POSTLOOP]], 1214; CHECK-NEXT: [[ABC_POSTLOOP:%.*]] = icmp ult i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]215; CHECK-NEXT: br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]216; CHECK: in.bounds.postloop:217; CHECK-NEXT: [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]218; CHECK-NEXT: store i32 0, ptr [[ADDR_POSTLOOP]], align 4219; CHECK-NEXT: [[NEXT_POSTLOOP:%.*]] = icmp ult i32 [[IDX_NEXT_POSTLOOP]], 2147483647220; CHECK-NEXT: br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP8:![0-9]+]], !loop_constrainer.loop.clone [[META6]]221;222 223entry:224 %len = load i32, ptr %a_len_ptr, !range !0225 br label %loop226 227loop:228 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]229 %idx.next = add nsw nuw i32 %idx, 1230 %abc = icmp ult i32 %idx, %len231 br i1 %abc, label %in.bounds, label %out.of.bounds232 233in.bounds:234 %addr = getelementptr i32, ptr %arr, i32 %idx235 store i32 0, ptr %addr236 %next = icmp ult i32 %idx.next, 2147483647237 br i1 %next, label %loop, label %exit238 239out.of.bounds:240 ret void241 242exit:243 ret void244}245 246; Check SINT_MAX + 1, test is similar to test_01.247define void @test_04(ptr %arr, ptr %a_len_ptr) #0 {248; CHECK-LABEL: define void @test_04249; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {250; CHECK-NEXT: entry:251; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]252; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]253; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]254; CHECK: loop.preheader:255; CHECK-NEXT: br label [[LOOP:%.*]]256; CHECK: loop:257; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]258; CHECK-NEXT: [[IDX_NEXT]] = add nuw nsw i32 [[IDX]], 1259; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[EXIT_MAINLOOP_AT]]260; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]261; CHECK: in.bounds:262; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]263; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4264; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], -2147483648265; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]266; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]267; CHECK: main.exit.selector:268; CHECK-NEXT: [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]269; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[IDX_NEXT_LCSSA]], -2147483648270; CHECK-NEXT: br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]271; CHECK: main.pseudo.exit:272; CHECK-NEXT: [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]273; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]274; CHECK-NEXT: br label [[POSTLOOP:%.*]]275; CHECK: out.of.bounds.loopexit:276; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]]277; CHECK: out.of.bounds.loopexit1:278; CHECK-NEXT: br label [[OUT_OF_BOUNDS]]279; CHECK: out.of.bounds:280; CHECK-NEXT: ret void281; CHECK: exit.loopexit:282; CHECK-NEXT: br label [[EXIT]]283; CHECK: exit:284; CHECK-NEXT: ret void285; CHECK: postloop:286; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]287; CHECK: loop.postloop:288; CHECK-NEXT: [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]289; CHECK-NEXT: [[IDX_NEXT_POSTLOOP]] = add nuw nsw i32 [[IDX_POSTLOOP]], 1290; CHECK-NEXT: [[ABC_POSTLOOP:%.*]] = icmp ult i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]291; CHECK-NEXT: br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]292; CHECK: in.bounds.postloop:293; CHECK-NEXT: [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]294; CHECK-NEXT: store i32 0, ptr [[ADDR_POSTLOOP]], align 4295; CHECK-NEXT: [[NEXT_POSTLOOP:%.*]] = icmp ult i32 [[IDX_NEXT_POSTLOOP]], -2147483648296; CHECK-NEXT: br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP9:![0-9]+]], !loop_constrainer.loop.clone [[META6]]297;298 299entry:300 %len = load i32, ptr %a_len_ptr, !range !0301 br label %loop302 303loop:304 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]305 %idx.next = add nsw nuw i32 %idx, 1306 %abc = icmp ult i32 %idx, %len307 br i1 %abc, label %in.bounds, label %out.of.bounds308 309in.bounds:310 %addr = getelementptr i32, ptr %arr, i32 %idx311 store i32 0, ptr %addr312 %next = icmp ult i32 %idx.next, 2147483648313 br i1 %next, label %loop, label %exit314 315out.of.bounds:316 ret void317 318exit:319 ret void320}321 322; Check SINT_MAX + 1, test is similar to test_02.323define void @test_05(ptr %arr, ptr %a_len_ptr) #0 {324; CHECK-LABEL: define void @test_05325; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {326; CHECK-NEXT: entry:327; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]328; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[LEN]], i32 1)329; CHECK-NEXT: [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[UMAX]], -1330; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 -2147483648, [[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 i32 [[IDX]], -1339; CHECK-NEXT: [[ABC:%.*]] = icmp ult 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 ult i32 [[IDX_NEXT]], 1345; CHECK-NEXT: br i1 [[NEXT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]]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:%.*]] ], [ -2147483648, [[LOOP_PRELOOP_PREHEADER]] ]358; CHECK-NEXT: [[IDX_NEXT_PRELOOP]] = add i32 [[IDX_PRELOOP]], -1359; CHECK-NEXT: [[ABC_PRELOOP:%.*]] = icmp ult 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 ult i32 [[IDX_NEXT_PRELOOP]], 1365; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP]], [[EXIT_PRELOOP_AT]]366; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true367; CHECK-NEXT: br i1 [[TMP2]], label [[PRELOOP_EXIT_SELECTOR:%.*]], label [[LOOP_PRELOOP]], !llvm.loop [[LOOP10:![0-9]+]], !loop_constrainer.loop.clone [[META6]]368; CHECK: preloop.exit.selector:369; CHECK-NEXT: [[IDX_NEXT_PRELOOP_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP]], [[IN_BOUNDS_PRELOOP]] ]370; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP_LCSSA]], 0371; CHECK-NEXT: br i1 [[TMP3]], label [[PRELOOP_PSEUDO_EXIT]], label [[EXIT]]372; CHECK: preloop.pseudo.exit:373; CHECK-NEXT: [[IDX_PRELOOP_COPY]] = phi i32 [ -2147483648, [[ENTRY:%.*]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]374; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ -2147483648, [[ENTRY]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]375; CHECK-NEXT: br label [[MAINLOOP]]376;377 378entry:379 %len = load i32, ptr %a_len_ptr, !range !0380 br label %loop381 382loop:383 %idx = phi i32 [ 2147483648, %entry ], [ %idx.next, %in.bounds ]384 %idx.next = add i32 %idx, -1385 %abc = icmp ult i32 %idx, %len386 br i1 %abc, label %in.bounds, label %out.of.bounds387 388in.bounds:389 %addr = getelementptr i32, ptr %arr, i32 %idx390 store i32 0, ptr %addr391 %next = icmp ult i32 %idx.next, 1392 br i1 %next, label %exit, label %loop393 394out.of.bounds:395 ret void396 397exit:398 ret void399}400 401; Increasing loop, UINT_MAX. Positive test.402define void @test_06(ptr %arr, ptr %a_len_ptr) #0 {403; CHECK-LABEL: define void @test_06404; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {405; CHECK-NEXT: entry:406; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]407; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]408; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]409; CHECK: loop.preheader:410; CHECK-NEXT: br label [[LOOP:%.*]]411; CHECK: loop:412; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]413; CHECK-NEXT: [[IDX_NEXT]] = add nuw nsw i32 [[IDX]], 1414; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[EXIT_MAINLOOP_AT]]415; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]416; CHECK: in.bounds:417; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]418; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4419; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], -1420; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]421; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]422; CHECK: main.exit.selector:423; CHECK-NEXT: [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]424; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[IDX_NEXT_LCSSA]], -1425; CHECK-NEXT: br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]426; CHECK: main.pseudo.exit:427; CHECK-NEXT: [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]428; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]429; CHECK-NEXT: br label [[POSTLOOP:%.*]]430; CHECK: out.of.bounds.loopexit:431; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]]432; CHECK: out.of.bounds.loopexit1:433; CHECK-NEXT: br label [[OUT_OF_BOUNDS]]434; CHECK: out.of.bounds:435; CHECK-NEXT: ret void436; CHECK: exit.loopexit:437; CHECK-NEXT: br label [[EXIT]]438; CHECK: exit:439; CHECK-NEXT: ret void440; CHECK: postloop:441; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]442; CHECK: loop.postloop:443; CHECK-NEXT: [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]444; CHECK-NEXT: [[IDX_NEXT_POSTLOOP]] = add nuw nsw i32 [[IDX_POSTLOOP]], 1445; CHECK-NEXT: [[ABC_POSTLOOP:%.*]] = icmp ult i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]446; CHECK-NEXT: br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]447; CHECK: in.bounds.postloop:448; CHECK-NEXT: [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]449; CHECK-NEXT: store i32 0, ptr [[ADDR_POSTLOOP]], align 4450; CHECK-NEXT: [[NEXT_POSTLOOP:%.*]] = icmp ult i32 [[IDX_NEXT_POSTLOOP]], -1451; CHECK-NEXT: br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP11:![0-9]+]], !loop_constrainer.loop.clone [[META6]]452;453 454entry:455 %len = load i32, ptr %a_len_ptr, !range !0456 br label %loop457 458loop:459 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]460 %idx.next = add nsw nuw i32 %idx, 1461 %abc = icmp ult 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 ult i32 %idx.next, 4294967295468 br i1 %next, label %loop, label %exit469 470out.of.bounds:471 ret void472 473exit:474 ret void475}476 477; Decreasing loop, UINT_MAX. Negative test: we cannot substract -1 from 0.478define void @test_07(ptr %arr, ptr %a_len_ptr) #0 {479; CHECK-LABEL: define void @test_07480; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {481; CHECK-NEXT: entry:482; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]483; CHECK-NEXT: br label [[LOOP:%.*]]484; CHECK: loop:485; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]486; CHECK-NEXT: [[IDX_NEXT]] = add nuw i32 [[IDX]], -1487; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[LEN]]488; CHECK-NEXT: br i1 [[ABC]], label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS:%.*]]489; CHECK: in.bounds:490; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]491; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4492; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], 0493; CHECK-NEXT: br i1 [[NEXT]], label [[EXIT:%.*]], label [[LOOP]]494; CHECK: out.of.bounds:495; CHECK-NEXT: ret void496; CHECK: exit:497; CHECK-NEXT: ret void498;499 500entry:501 %len = load i32, ptr %a_len_ptr, !range !0502 br label %loop503 504loop:505 %idx = phi i32 [ 4294967295, %entry ], [ %idx.next, %in.bounds ]506 %idx.next = add nuw i32 %idx, -1507 %abc = icmp ult i32 %idx, %len508 br i1 %abc, label %in.bounds, label %out.of.bounds509 510in.bounds:511 %addr = getelementptr i32, ptr %arr, i32 %idx512 store i32 0, ptr %addr513 %next = icmp ult i32 %idx.next, 0514 br i1 %next, label %exit, label %loop515 516out.of.bounds:517 ret void518 519exit:520 ret void521}522 523; Unsigned walking through signed border is allowed.524; Iteration space [0; UINT_MAX - 99), the fact that SINT_MAX is within this525; range does not prevent us from performing IRCE.526 527define void @test_08(ptr %arr, ptr %a_len_ptr) #0 {528; CHECK-LABEL: define void @test_08529; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {530; CHECK-NEXT: entry:531; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]532; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]533; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]534; CHECK: loop.preheader:535; CHECK-NEXT: br label [[LOOP:%.*]]536; CHECK: loop:537; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]538; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], 1539; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[EXIT_MAINLOOP_AT]]540; CHECK-NEXT: br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]541; CHECK: in.bounds:542; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]543; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4544; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], -100545; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]546; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]547; CHECK: main.exit.selector:548; CHECK-NEXT: [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]549; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[IDX_NEXT_LCSSA]], -100550; CHECK-NEXT: br i1 [[TMP2]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]551; CHECK: main.pseudo.exit:552; CHECK-NEXT: [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]553; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]554; CHECK-NEXT: br label [[POSTLOOP:%.*]]555; CHECK: out.of.bounds.loopexit:556; CHECK-NEXT: br label [[OUT_OF_BOUNDS:%.*]]557; CHECK: out.of.bounds.loopexit1:558; CHECK-NEXT: br label [[OUT_OF_BOUNDS]]559; CHECK: out.of.bounds:560; CHECK-NEXT: ret void561; CHECK: exit.loopexit:562; CHECK-NEXT: br label [[EXIT]]563; CHECK: exit:564; CHECK-NEXT: ret void565; CHECK: postloop:566; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]567; CHECK: loop.postloop:568; CHECK-NEXT: [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]569; CHECK-NEXT: [[IDX_NEXT_POSTLOOP]] = add i32 [[IDX_POSTLOOP]], 1570; CHECK-NEXT: [[ABC_POSTLOOP:%.*]] = icmp ult i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]571; CHECK-NEXT: br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]572; CHECK: in.bounds.postloop:573; CHECK-NEXT: [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]574; CHECK-NEXT: store i32 0, ptr [[ADDR_POSTLOOP]], align 4575; CHECK-NEXT: [[NEXT_POSTLOOP:%.*]] = icmp ult i32 [[IDX_NEXT_POSTLOOP]], -100576; CHECK-NEXT: br i1 [[NEXT_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP12:![0-9]+]], !loop_constrainer.loop.clone [[META6]]577;578 579entry:580 %len = load i32, ptr %a_len_ptr, !range !0581 br label %loop582 583loop:584 %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]585 %idx.next = add i32 %idx, 1586 %abc = icmp ult i32 %idx, %len587 br i1 %abc, label %in.bounds, label %out.of.bounds588 589in.bounds:590 %addr = getelementptr i32, ptr %arr, i32 %idx591 store i32 0, ptr %addr592 %next = icmp ult i32 %idx.next, -100593 br i1 %next, label %loop, label %exit594 595out.of.bounds:596 ret void597 598exit:599 ret void600}601 602; Walking through the border of unsigned range is not allowed603; (iteration space [-100; 100)). Negative test.604 605define void @test_09(ptr %arr, ptr %a_len_ptr) #0 {606; CHECK-LABEL: define void @test_09607; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {608; CHECK-NEXT: entry:609; CHECK-NEXT: [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]610; CHECK-NEXT: br label [[LOOP:%.*]]611; CHECK: loop:612; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ -100, [[ENTRY:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]613; CHECK-NEXT: [[IDX_NEXT]] = add i32 [[IDX]], 1614; CHECK-NEXT: [[ABC:%.*]] = icmp ult i32 [[IDX]], [[LEN]]615; CHECK-NEXT: br i1 [[ABC]], label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS:%.*]]616; CHECK: in.bounds:617; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]618; CHECK-NEXT: store i32 0, ptr [[ADDR]], align 4619; CHECK-NEXT: [[NEXT:%.*]] = icmp ult i32 [[IDX_NEXT]], 100620; CHECK-NEXT: br i1 [[NEXT]], label [[LOOP]], label [[EXIT:%.*]]621; CHECK: out.of.bounds:622; CHECK-NEXT: ret void623; CHECK: exit:624; CHECK-NEXT: ret void625;626 627entry:628 %len = load i32, ptr %a_len_ptr, !range !0629 br label %loop630 631loop:632 %idx = phi i32 [ -100, %entry ], [ %idx.next, %in.bounds ]633 %idx.next = add i32 %idx, 1634 %abc = icmp ult i32 %idx, %len635 br i1 %abc, label %in.bounds, label %out.of.bounds636 637in.bounds:638 %addr = getelementptr i32, ptr %arr, i32 %idx639 store i32 0, ptr %addr640 %next = icmp ult i32 %idx.next, 100641 br i1 %next, label %loop, label %exit642 643out.of.bounds:644 ret void645 646exit:647 ret void648}649 650!0 = !{i32 0, i32 50}651;.652; CHECK: [[RNG0]] = !{i32 0, i32 50}653; CHECK: [[LOOP1]] = distinct !{[[LOOP1]], [[META2:![0-9]+]], [[META3:![0-9]+]], [[META4:![0-9]+]], [[META5:![0-9]+]]}654; CHECK: [[META2]] = !{!"llvm.loop.unroll.disable"}655; CHECK: [[META3]] = !{!"llvm.loop.vectorize.enable", i1 false}656; CHECK: [[META4]] = !{!"llvm.loop.licm_versioning.disable"}657; CHECK: [[META5]] = !{!"llvm.loop.distribute.enable", i1 false}658; CHECK: [[META6]] = !{}659; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META2]], [[META3]], [[META4]], [[META5]]}660; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META2]], [[META3]], [[META4]], [[META5]]}661; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META2]], [[META3]], [[META4]], [[META5]]}662; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META2]], [[META3]], [[META4]], [[META5]]}663; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META2]], [[META3]], [[META4]], [[META5]]}664; CHECK: [[LOOP12]] = distinct !{[[LOOP12]], [[META2]], [[META3]], [[META4]], [[META5]]}665;.666