brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.4 KiB · 7236cf4 Raw
457 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-NOT: 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 12; UGT condition for increasing loop.13define void @test_01(ptr %arr, ptr %a_len_ptr) #0 {14; CHECK-LABEL: define void @test_0115; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {16; CHECK-NEXT:  entry:17; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0:![0-9]+]]18; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]19; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]20; CHECK:       loop.preheader:21; CHECK-NEXT:    br label [[LOOP:%.*]]22; CHECK:       loop:23; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]24; CHECK-NEXT:    [[IDX_NEXT]] = add nuw nsw i32 [[IDX]], 125; CHECK-NEXT:    [[ABC:%.*]] = icmp ult i32 [[IDX]], [[EXIT_MAINLOOP_AT]]26; CHECK-NEXT:    br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]27; CHECK:       in.bounds:28; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]29; CHECK-NEXT:    store i32 0, ptr [[ADDR]], align 430; CHECK-NEXT:    [[NEXT:%.*]] = icmp ugt i32 [[IDX_NEXT]], 10031; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]32; CHECK-NEXT:    [[TMP2:%.*]] = xor i1 [[TMP1]], true33; CHECK-NEXT:    br i1 [[TMP2]], label [[MAIN_EXIT_SELECTOR:%.*]], label [[LOOP]]34; CHECK:       main.exit.selector:35; CHECK-NEXT:    [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]36; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i32 [[IDX_NEXT_LCSSA]], 10137; CHECK-NEXT:    br i1 [[TMP3]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]38; CHECK:       main.pseudo.exit:39; CHECK-NEXT:    [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]40; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]41; CHECK-NEXT:    br label [[POSTLOOP:%.*]]42; CHECK:       out.of.bounds.loopexit:43; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]44; CHECK:       out.of.bounds.loopexit1:45; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]46; CHECK:       out.of.bounds:47; CHECK-NEXT:    ret void48; CHECK:       exit.loopexit:49; CHECK-NEXT:    br label [[EXIT]]50; CHECK:       exit:51; CHECK-NEXT:    ret void52; CHECK:       postloop:53; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]54; CHECK:       loop.postloop:55; CHECK-NEXT:    [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]56; CHECK-NEXT:    [[IDX_NEXT_POSTLOOP]] = add nuw nsw i32 [[IDX_POSTLOOP]], 157; CHECK-NEXT:    [[ABC_POSTLOOP:%.*]] = icmp ult i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]58; CHECK-NEXT:    br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]59; CHECK:       in.bounds.postloop:60; CHECK-NEXT:    [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]61; CHECK-NEXT:    store i32 0, ptr [[ADDR_POSTLOOP]], align 462; CHECK-NEXT:    [[NEXT_POSTLOOP:%.*]] = icmp ugt i32 [[IDX_NEXT_POSTLOOP]], 10063; CHECK-NEXT:    br i1 [[NEXT_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_POSTLOOP]], !llvm.loop [[LOOP1:![0-9]+]], !loop_constrainer.loop.clone [[META6:![0-9]+]]64;65 66entry:67  %len = load i32, ptr %a_len_ptr, !range !068  br label %loop69 70loop:71  %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]72  %idx.next = add nsw nuw i32 %idx, 173  %abc = icmp ult i32 %idx, %len74  br i1 %abc, label %in.bounds, label %out.of.bounds75 76in.bounds:77  %addr = getelementptr i32, ptr %arr, i32 %idx78  store i32 0, ptr %addr79  %next = icmp ugt i32 %idx.next, 10080  br i1 %next, label %exit, label %loop81 82out.of.bounds:83  ret void84 85exit:86  ret void87}88 89; UGT condition for decreasing loop.90define void @test_02(ptr %arr, ptr %a_len_ptr) #0 {91; CHECK-LABEL: define void @test_0292; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {93; CHECK-NEXT:  entry:94; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]95; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[LEN]], i32 1)96; CHECK-NEXT:    [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[UMAX]], -197; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 100, [[EXIT_PRELOOP_AT]]98; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]99; CHECK:       loop.preloop.preheader:100; CHECK-NEXT:    br label [[LOOP_PRELOOP:%.*]]101; CHECK:       mainloop:102; CHECK-NEXT:    br label [[LOOP:%.*]]103; CHECK:       loop:104; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_PRELOOP_COPY:%.*]], [[MAINLOOP:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]105; CHECK-NEXT:    [[IDX_NEXT]] = add i32 [[IDX]], -1106; CHECK-NEXT:    [[ABC:%.*]] = icmp ult i32 [[IDX]], [[LEN]]107; CHECK-NEXT:    br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]108; CHECK:       in.bounds:109; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]110; CHECK-NEXT:    store i32 0, ptr [[ADDR]], align 4111; CHECK-NEXT:    [[NEXT:%.*]] = icmp ugt i32 [[IDX_NEXT]], 0112; CHECK-NEXT:    br i1 [[NEXT]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]113; CHECK:       out.of.bounds.loopexit:114; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]115; CHECK:       out.of.bounds.loopexit1:116; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]117; CHECK:       out.of.bounds:118; CHECK-NEXT:    ret void119; CHECK:       exit.loopexit:120; CHECK-NEXT:    br label [[EXIT:%.*]]121; CHECK:       exit:122; CHECK-NEXT:    ret void123; CHECK:       loop.preloop:124; CHECK-NEXT:    [[IDX_PRELOOP:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP:%.*]], [[IN_BOUNDS_PRELOOP:%.*]] ], [ 100, [[LOOP_PRELOOP_PREHEADER]] ]125; CHECK-NEXT:    [[IDX_NEXT_PRELOOP]] = add i32 [[IDX_PRELOOP]], -1126; CHECK-NEXT:    [[ABC_PRELOOP:%.*]] = icmp ult i32 [[IDX_PRELOOP]], [[LEN]]127; CHECK-NEXT:    br i1 [[ABC_PRELOOP]], label [[IN_BOUNDS_PRELOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]128; CHECK:       in.bounds.preloop:129; CHECK-NEXT:    [[ADDR_PRELOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_PRELOOP]]130; CHECK-NEXT:    store i32 0, ptr [[ADDR_PRELOOP]], align 4131; CHECK-NEXT:    [[NEXT_PRELOOP:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP]], 0132; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP]], [[EXIT_PRELOOP_AT]]133; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP7:![0-9]+]], !loop_constrainer.loop.clone [[META6]]134; CHECK:       preloop.exit.selector:135; CHECK-NEXT:    [[IDX_NEXT_PRELOOP_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP]], [[IN_BOUNDS_PRELOOP]] ]136; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP_LCSSA]], 0137; CHECK-NEXT:    br i1 [[TMP2]], label [[PRELOOP_PSEUDO_EXIT]], label [[EXIT]]138; CHECK:       preloop.pseudo.exit:139; CHECK-NEXT:    [[IDX_PRELOOP_COPY]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]140; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 100, [[ENTRY]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]141; CHECK-NEXT:    br label [[MAINLOOP]]142;143 144entry:145  %len = load i32, ptr %a_len_ptr, !range !0146  br label %loop147 148loop:149  %idx = phi i32 [ 100, %entry ], [ %idx.next, %in.bounds ]150  %idx.next = add i32 %idx, -1151  %abc = icmp ult i32 %idx, %len152  br i1 %abc, label %in.bounds, label %out.of.bounds153 154in.bounds:155  %addr = getelementptr i32, ptr %arr, i32 %idx156  store i32 0, ptr %addr157  %next = icmp ugt i32 %idx.next, 0158  br i1 %next, label %loop, label %exit159 160out.of.bounds:161  ret void162 163exit:164  ret void165}166 167; Check SINT_MAX + 1, test is similar to test_01.168define void @test_03(ptr %arr, ptr %a_len_ptr) #0 {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 [[RNG0]]173; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult 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 nuw nsw i32 [[IDX]], 1180; CHECK-NEXT:    [[ABC:%.*]] = icmp ult 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 ugt i32 [[IDX_NEXT]], -2147483648186; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[IDX_NEXT]], [[EXIT_MAINLOOP_AT]]187; CHECK-NEXT:    [[TMP2:%.*]] = xor i1 [[TMP1]], true188; CHECK-NEXT:    br i1 [[TMP2]], label [[MAIN_EXIT_SELECTOR:%.*]], label [[LOOP]]189; CHECK:       main.exit.selector:190; CHECK-NEXT:    [[IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT]], [[IN_BOUNDS]] ]191; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i32 [[IDX_NEXT_LCSSA]], -2147483647192; CHECK-NEXT:    br i1 [[TMP3]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]193; CHECK:       main.pseudo.exit:194; CHECK-NEXT:    [[IDX_COPY:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]195; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IDX_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]196; CHECK-NEXT:    br label [[POSTLOOP:%.*]]197; CHECK:       out.of.bounds.loopexit:198; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]199; CHECK:       out.of.bounds.loopexit1:200; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]201; CHECK:       out.of.bounds:202; CHECK-NEXT:    ret void203; CHECK:       exit.loopexit:204; CHECK-NEXT:    br label [[EXIT]]205; CHECK:       exit:206; CHECK-NEXT:    ret void207; CHECK:       postloop:208; CHECK-NEXT:    br label [[LOOP_POSTLOOP:%.*]]209; CHECK:       loop.postloop:210; CHECK-NEXT:    [[IDX_POSTLOOP:%.*]] = phi i32 [ [[IDX_COPY]], [[POSTLOOP]] ], [ [[IDX_NEXT_POSTLOOP:%.*]], [[IN_BOUNDS_POSTLOOP:%.*]] ]211; CHECK-NEXT:    [[IDX_NEXT_POSTLOOP]] = add nuw nsw i32 [[IDX_POSTLOOP]], 1212; CHECK-NEXT:    [[ABC_POSTLOOP:%.*]] = icmp ult i32 [[IDX_POSTLOOP]], [[EXIT_MAINLOOP_AT]]213; CHECK-NEXT:    br i1 [[ABC_POSTLOOP]], label [[IN_BOUNDS_POSTLOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]214; CHECK:       in.bounds.postloop:215; CHECK-NEXT:    [[ADDR_POSTLOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_POSTLOOP]]216; CHECK-NEXT:    store i32 0, ptr [[ADDR_POSTLOOP]], align 4217; CHECK-NEXT:    [[NEXT_POSTLOOP:%.*]] = icmp ugt i32 [[IDX_NEXT_POSTLOOP]], -2147483648218; CHECK-NEXT:    br i1 [[NEXT_POSTLOOP]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_POSTLOOP]], !llvm.loop [[LOOP8:![0-9]+]], !loop_constrainer.loop.clone [[META6]]219;220 221entry:222  %len = load i32, ptr %a_len_ptr, !range !0223  br label %loop224 225loop:226  %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]227  %idx.next = add nsw nuw i32 %idx, 1228  %abc = icmp ult i32 %idx, %len229  br i1 %abc, label %in.bounds, label %out.of.bounds230 231in.bounds:232  %addr = getelementptr i32, ptr %arr, i32 %idx233  store i32 0, ptr %addr234  %next = icmp ugt i32 %idx.next, 2147483648235  br i1 %next, label %exit, label %loop236 237out.of.bounds:238  ret void239 240exit:241  ret void242}243 244; Check SINT_MAX + 1, test is similar to test_02.245define void @test_04(ptr %arr, ptr %a_len_ptr) #0 {246; CHECK-LABEL: define void @test_04247; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {248; CHECK-NEXT:  entry:249; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]250; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[LEN]], i32 1)251; CHECK-NEXT:    [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[UMAX]], -1252; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 -2147483648, [[EXIT_PRELOOP_AT]]253; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]254; CHECK:       loop.preloop.preheader:255; CHECK-NEXT:    br label [[LOOP_PRELOOP:%.*]]256; CHECK:       mainloop:257; CHECK-NEXT:    br label [[LOOP:%.*]]258; CHECK:       loop:259; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_PRELOOP_COPY:%.*]], [[MAINLOOP:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]260; CHECK-NEXT:    [[IDX_NEXT]] = add i32 [[IDX]], -1261; CHECK-NEXT:    [[ABC:%.*]] = icmp ult i32 [[IDX]], [[LEN]]262; CHECK-NEXT:    br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]263; CHECK:       in.bounds:264; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]265; CHECK-NEXT:    store i32 0, ptr [[ADDR]], align 4266; CHECK-NEXT:    [[NEXT:%.*]] = icmp ugt i32 [[IDX_NEXT]], 0267; CHECK-NEXT:    br i1 [[NEXT]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]268; CHECK:       out.of.bounds.loopexit:269; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]270; CHECK:       out.of.bounds.loopexit1:271; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]272; CHECK:       out.of.bounds:273; CHECK-NEXT:    ret void274; CHECK:       exit.loopexit:275; CHECK-NEXT:    br label [[EXIT:%.*]]276; CHECK:       exit:277; CHECK-NEXT:    ret void278; CHECK:       loop.preloop:279; CHECK-NEXT:    [[IDX_PRELOOP:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP:%.*]], [[IN_BOUNDS_PRELOOP:%.*]] ], [ -2147483648, [[LOOP_PRELOOP_PREHEADER]] ]280; CHECK-NEXT:    [[IDX_NEXT_PRELOOP]] = add i32 [[IDX_PRELOOP]], -1281; CHECK-NEXT:    [[ABC_PRELOOP:%.*]] = icmp ult i32 [[IDX_PRELOOP]], [[LEN]]282; CHECK-NEXT:    br i1 [[ABC_PRELOOP]], label [[IN_BOUNDS_PRELOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]283; CHECK:       in.bounds.preloop:284; CHECK-NEXT:    [[ADDR_PRELOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_PRELOOP]]285; CHECK-NEXT:    store i32 0, ptr [[ADDR_PRELOOP]], align 4286; CHECK-NEXT:    [[NEXT_PRELOOP:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP]], 0287; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP]], [[EXIT_PRELOOP_AT]]288; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP9:![0-9]+]], !loop_constrainer.loop.clone [[META6]]289; CHECK:       preloop.exit.selector:290; CHECK-NEXT:    [[IDX_NEXT_PRELOOP_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP]], [[IN_BOUNDS_PRELOOP]] ]291; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP_LCSSA]], 0292; CHECK-NEXT:    br i1 [[TMP2]], label [[PRELOOP_PSEUDO_EXIT]], label [[EXIT]]293; CHECK:       preloop.pseudo.exit:294; CHECK-NEXT:    [[IDX_PRELOOP_COPY]] = phi i32 [ -2147483648, [[ENTRY:%.*]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]295; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ -2147483648, [[ENTRY]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]296; CHECK-NEXT:    br label [[MAINLOOP]]297;298 299entry:300  %len = load i32, ptr %a_len_ptr, !range !0301  br label %loop302 303loop:304  %idx = phi i32 [ 2147483648, %entry ], [ %idx.next, %in.bounds ]305  %idx.next = add 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 ugt i32 %idx.next, 0313  br i1 %next, label %loop, label %exit314 315out.of.bounds:316  ret void317 318exit:319  ret void320}321 322; Increasing loop, UINT_MAX. Negative test: we cannot add 1 to UINT_MAX.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:    br label [[LOOP:%.*]]329; CHECK:       loop:330; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]331; CHECK-NEXT:    [[IDX_NEXT]] = add nuw nsw i32 [[IDX]], 1332; CHECK-NEXT:    [[ABC:%.*]] = icmp ult i32 [[IDX]], [[LEN]]333; CHECK-NEXT:    br i1 [[ABC]], label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS:%.*]]334; CHECK:       in.bounds:335; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]336; CHECK-NEXT:    store i32 0, ptr [[ADDR]], align 4337; CHECK-NEXT:    [[NEXT:%.*]] = icmp ugt i32 [[IDX_NEXT]], -1338; CHECK-NEXT:    br i1 [[NEXT]], label [[EXIT:%.*]], label [[LOOP]]339; CHECK:       out.of.bounds:340; CHECK-NEXT:    ret void341; CHECK:       exit:342; CHECK-NEXT:    ret void343;344 345entry:346  %len = load i32, ptr %a_len_ptr, !range !0347  br label %loop348 349loop:350  %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]351  %idx.next = add nsw nuw i32 %idx, 1352  %abc = icmp ult i32 %idx, %len353  br i1 %abc, label %in.bounds, label %out.of.bounds354 355in.bounds:356  %addr = getelementptr i32, ptr %arr, i32 %idx357  store i32 0, ptr %addr358  %next = icmp ugt i32 %idx.next, 4294967295359  br i1 %next, label %exit, label %loop360 361out.of.bounds:362  ret void363 364exit:365  ret void366}367 368; Decreasing loop, UINT_MAX. Positive test.369define void @test_06(ptr %arr, ptr %a_len_ptr) #0 {370; CHECK-LABEL: define void @test_06371; CHECK-SAME: (ptr [[ARR:%.*]], ptr [[A_LEN_PTR:%.*]]) {372; CHECK-NEXT:  entry:373; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[A_LEN_PTR]], align 4, !range [[RNG0]]374; CHECK-NEXT:    br i1 true, label [[LOOP_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]375; CHECK:       loop.preloop.preheader:376; CHECK-NEXT:    br label [[LOOP_PRELOOP:%.*]]377; CHECK:       mainloop:378; CHECK-NEXT:    br label [[LOOP:%.*]]379; CHECK:       loop:380; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_PRELOOP_COPY:%.*]], [[MAINLOOP:%.*]] ], [ [[IDX_NEXT:%.*]], [[IN_BOUNDS:%.*]] ]381; CHECK-NEXT:    [[IDX_NEXT]] = add nuw i32 [[IDX]], -1382; CHECK-NEXT:    [[ABC:%.*]] = icmp ult i32 [[IDX]], [[LEN]]383; CHECK-NEXT:    br i1 true, label [[IN_BOUNDS]], label [[OUT_OF_BOUNDS_LOOPEXIT1:%.*]]384; CHECK:       in.bounds:385; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX]]386; CHECK-NEXT:    store i32 0, ptr [[ADDR]], align 4387; CHECK-NEXT:    [[NEXT:%.*]] = icmp ugt i32 [[IDX_NEXT]], 0388; CHECK-NEXT:    br i1 [[NEXT]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]389; CHECK:       out.of.bounds.loopexit:390; CHECK-NEXT:    br label [[OUT_OF_BOUNDS:%.*]]391; CHECK:       out.of.bounds.loopexit1:392; CHECK-NEXT:    br label [[OUT_OF_BOUNDS]]393; CHECK:       out.of.bounds:394; CHECK-NEXT:    ret void395; CHECK:       exit.loopexit:396; CHECK-NEXT:    br label [[EXIT:%.*]]397; CHECK:       exit:398; CHECK-NEXT:    ret void399; CHECK:       loop.preloop:400; CHECK-NEXT:    [[IDX_PRELOOP:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP:%.*]], [[IN_BOUNDS_PRELOOP:%.*]] ], [ -1, [[LOOP_PRELOOP_PREHEADER]] ]401; CHECK-NEXT:    [[IDX_NEXT_PRELOOP]] = add nuw i32 [[IDX_PRELOOP]], -1402; CHECK-NEXT:    [[ABC_PRELOOP:%.*]] = icmp ult i32 [[IDX_PRELOOP]], [[LEN]]403; CHECK-NEXT:    br i1 [[ABC_PRELOOP]], label [[IN_BOUNDS_PRELOOP]], label [[OUT_OF_BOUNDS_LOOPEXIT:%.*]]404; CHECK:       in.bounds.preloop:405; CHECK-NEXT:    [[ADDR_PRELOOP:%.*]] = getelementptr i32, ptr [[ARR]], i32 [[IDX_PRELOOP]]406; CHECK-NEXT:    store i32 0, ptr [[ADDR_PRELOOP]], align 4407; CHECK-NEXT:    [[NEXT_PRELOOP:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP]], 0408; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP]], 0409; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP10:![0-9]+]], !loop_constrainer.loop.clone [[META6]]410; CHECK:       preloop.exit.selector:411; CHECK-NEXT:    [[IDX_NEXT_PRELOOP_LCSSA:%.*]] = phi i32 [ [[IDX_NEXT_PRELOOP]], [[IN_BOUNDS_PRELOOP]] ]412; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[IDX_NEXT_PRELOOP_LCSSA]], 0413; CHECK-NEXT:    br i1 [[TMP1]], label [[PRELOOP_PSEUDO_EXIT]], label [[EXIT]]414; CHECK:       preloop.pseudo.exit:415; CHECK-NEXT:    [[IDX_PRELOOP_COPY]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]416; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ -1, [[ENTRY]] ], [ [[IDX_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]417; CHECK-NEXT:    br label [[MAINLOOP]]418;419 420entry:421  %len = load i32, ptr %a_len_ptr, !range !0422  br label %loop423 424loop:425  %idx = phi i32 [ 4294967295, %entry ], [ %idx.next, %in.bounds ]426  %idx.next = add nuw i32 %idx, -1427  %abc = icmp ult i32 %idx, %len428  br i1 %abc, label %in.bounds, label %out.of.bounds429 430in.bounds:431  %addr = getelementptr i32, ptr %arr, i32 %idx432  store i32 0, ptr %addr433  %next = icmp ugt i32 %idx.next, 0434  br i1 %next, label %loop, label %exit435 436out.of.bounds:437  ret void438 439exit:440  ret void441}442 443!0 = !{i32 0, i32 50}444;.445; CHECK: [[RNG0]] = !{i32 0, i32 50}446; CHECK: [[LOOP1]] = distinct !{[[LOOP1]], [[META2:![0-9]+]], [[META3:![0-9]+]], [[META4:![0-9]+]], [[META5:![0-9]+]]}447; CHECK: [[META2]] = !{!"llvm.loop.unroll.disable"}448; CHECK: [[META3]] = !{!"llvm.loop.vectorize.enable", i1 false}449; CHECK: [[META4]] = !{!"llvm.loop.licm_versioning.disable"}450; CHECK: [[META5]] = !{!"llvm.loop.distribute.enable", i1 false}451; CHECK: [[META6]] = !{}452; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META2]], [[META3]], [[META4]], [[META5]]}453; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META2]], [[META3]], [[META4]], [[META5]]}454; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META2]], [[META3]], [[META4]], [[META5]]}455; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META2]], [[META3]], [[META4]], [[META5]]}456;.457