316 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -p loop-unroll -unroll-full-max-count=0 -S %s | FileCheck %s3 4declare void @foo(i32)5declare i1 @cond()6 7define i64 @loop_with_3_exits(i64 %n) {8; CHECK-LABEL: define i64 @loop_with_3_exits(9; CHECK-SAME: i64 [[N:%.*]]) {10; CHECK-NEXT: [[ENTRY:.*]]:11; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]12; CHECK: [[LOOP_HEADER]]:13; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]14; CHECK-NEXT: br i1 false, label %[[LOOP_LATCH]], label %[[THEN:.*]]15; CHECK: [[THEN]]:16; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[IV]], [[N]]17; CHECK-NEXT: br i1 [[C]], label %[[EXIT_0:.*]], label %[[THEN_2:.*]]18; CHECK: [[THEN_2]]:19; CHECK-NEXT: call void @foo(i32 0)20; CHECK-NEXT: br label %[[LOOP_LATCH]]21; CHECK: [[LOOP_LATCH]]:22; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 123; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 6324; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_1:.*]], label %[[LOOP_HEADER]]25; CHECK: [[EXIT_0]]:26; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[THEN]] ]27; CHECK-NEXT: ret i64 [[IV_LCSSA]]28; CHECK: [[EXIT_1]]:29; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], %[[LOOP_LATCH]] ]30; CHECK-NEXT: ret i64 [[IV_NEXT_LCSSA]]31;32entry:33 br label %loop.header34 35loop.header:36 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]37 br i1 false, label %loop.latch, label %then38 39then:40 %c = icmp eq i64 %iv, %n41 br i1 %c, label %exit.0, label %then.242 43then.2:44 call void @foo(i32 0)45 br label %loop.latch46 47loop.latch:48 %iv.next = add i64 %iv, 149 %ec = icmp eq i64 %iv, 6350 br i1 %ec, label %exit.1, label %loop.header51 52exit.0:53 ret i64 %iv54 55exit.1:56 ret i64 %iv.next57}58 59define void @peel_last_multi_exit_btc_computable_no_exit_values(i32 %n) {60; CHECK-LABEL: define void @peel_last_multi_exit_btc_computable_no_exit_values(61; CHECK-SAME: i32 [[N:%.*]]) {62; CHECK-NEXT: [[ENTRY:.*]]:63; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]64; CHECK: [[LOOP_HEADER]]:65; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_PEEL:%.*]], %[[LOOP_LATCH:.*]] ]66; CHECK-NEXT: [[EC_0_PEEL:%.*]] = icmp eq i32 [[IV_NEXT_LCSSA]], [[N]]67; CHECK-NEXT: br i1 [[EC_0_PEEL]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]68; CHECK: [[LOOP_LATCH]]:69; CHECK-NEXT: [[C_PEEL:%.*]] = icmp eq i32 [[IV_NEXT_LCSSA]], 1670; CHECK-NEXT: [[COND_PEEL:%.*]] = select i1 [[C_PEEL]], i32 10, i32 2071; CHECK-NEXT: call void @foo(i32 [[COND_PEEL]])72; CHECK-NEXT: [[IV_NEXT_PEEL]] = add i32 [[IV_NEXT_LCSSA]], 173; CHECK-NEXT: [[EC_PEEL:%.*]] = icmp eq i32 [[IV_NEXT_PEEL]], 1774; CHECK-NEXT: br i1 [[EC_PEEL]], label %[[EXIT]], label %[[LOOP_HEADER]]75; CHECK: [[EXIT]]:76; CHECK-NEXT: ret void77;78entry:79 br label %loop.header80 81loop.header:82 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]83 %ec.0 = icmp eq i32 %iv, %n84 br i1 %ec.0, label %exit, label %loop.latch85 86loop.latch:87 %c = icmp eq i32 %iv, 1688 %cond = select i1 %c, i32 10, i32 2089 call void @foo(i32 %cond)90 %iv.next = add i32 %iv, 191 %ec = icmp eq i32 %iv.next, 1792 br i1 %ec, label %exit, label %loop.header93 94exit:95 ret void96}97 98define i32 @peel_last_multi_exit_btc_computable_exit_constant_values(i32 %n) {99; CHECK-LABEL: define i32 @peel_last_multi_exit_btc_computable_exit_constant_values(100; CHECK-SAME: i32 [[N:%.*]]) {101; CHECK-NEXT: [[ENTRY:.*]]:102; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]103; CHECK: [[LOOP_HEADER]]:104; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_PEEL:%.*]], %[[LOOP_LATCH:.*]] ]105; CHECK-NEXT: [[EC_0_PEEL:%.*]] = icmp eq i32 [[IV_NEXT_LCSSA]], [[N]]106; CHECK-NEXT: br i1 [[EC_0_PEEL]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]107; CHECK: [[LOOP_LATCH]]:108; CHECK-NEXT: [[C_PEEL:%.*]] = icmp eq i32 [[IV_NEXT_LCSSA]], 16109; CHECK-NEXT: [[COND_PEEL:%.*]] = select i1 [[C_PEEL]], i32 10, i32 20110; CHECK-NEXT: call void @foo(i32 [[COND_PEEL]])111; CHECK-NEXT: [[IV_NEXT_PEEL]] = add i32 [[IV_NEXT_LCSSA]], 1112; CHECK-NEXT: [[EC_PEEL:%.*]] = icmp eq i32 [[IV_NEXT_PEEL]], 17113; CHECK-NEXT: br i1 [[EC_PEEL]], label %[[EXIT]], label %[[LOOP_HEADER]]114; CHECK: [[EXIT]]:115; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 1, %[[LOOP_HEADER]] ], [ 2, %[[LOOP_LATCH]] ]116; CHECK-NEXT: ret i32 [[RES]]117;118entry:119 br label %loop.header120 121loop.header:122 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]123 %ec.0 = icmp eq i32 %iv, %n124 br i1 %ec.0, label %exit, label %loop.latch125 126loop.latch:127 %c = icmp eq i32 %iv, 16128 %cond = select i1 %c, i32 10, i32 20129 call void @foo(i32 %cond)130 %iv.next = add i32 %iv, 1131 %ec = icmp eq i32 %iv.next, 17132 br i1 %ec, label %exit, label %loop.header133 134exit:135 %res = phi i32 [ 1, %loop.header ], [ 2, %loop.latch ]136 ret i32 %res137}138 139define i32 @peel_last_multi_exit_btc_computable_exit_values_from_loop(i32 %n) {140; CHECK-LABEL: define i32 @peel_last_multi_exit_btc_computable_exit_values_from_loop(141; CHECK-SAME: i32 [[N:%.*]]) {142; CHECK-NEXT: [[ENTRY:.*]]:143; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]144; CHECK: [[LOOP_HEADER]]:145; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_PEEL:%.*]], %[[LOOP_LATCH:.*]] ]146; CHECK-NEXT: [[EC_0_PEEL:%.*]] = icmp eq i32 [[IV_NEXT_LCSSA]], [[N]]147; CHECK-NEXT: br i1 [[EC_0_PEEL]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]148; CHECK: [[LOOP_LATCH]]:149; CHECK-NEXT: [[C_PEEL:%.*]] = icmp eq i32 [[IV_NEXT_LCSSA]], 16150; CHECK-NEXT: [[COND_PEEL:%.*]] = select i1 [[C_PEEL]], i32 10, i32 20151; CHECK-NEXT: call void @foo(i32 [[COND_PEEL]])152; CHECK-NEXT: [[IV_NEXT_PEEL]] = add i32 [[IV_NEXT_LCSSA]], 1153; CHECK-NEXT: [[EC_PEEL:%.*]] = icmp eq i32 [[IV_NEXT_PEEL]], 17154; CHECK-NEXT: br i1 [[EC_PEEL]], label %[[EXIT]], label %[[LOOP_HEADER]]155; CHECK: [[EXIT]]:156; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[IV_NEXT_LCSSA]], %[[LOOP_HEADER]] ], [ [[COND_PEEL]], %[[LOOP_LATCH]] ]157; CHECK-NEXT: ret i32 [[RES]]158;159entry:160 br label %loop.header161 162loop.header:163 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]164 %ec.0 = icmp eq i32 %iv, %n165 br i1 %ec.0, label %exit, label %loop.latch166 167loop.latch:168 %c = icmp eq i32 %iv, 16169 %cond = select i1 %c, i32 10, i32 20170 call void @foo(i32 %cond)171 %iv.next = add i32 %iv, 1172 %ec = icmp eq i32 %iv.next, 17173 br i1 %ec, label %exit, label %loop.header174 175exit:176 %res = phi i32 [ %iv, %loop.header ], [ %cond, %loop.latch ]177 ret i32 %res178}179 180define i32 @peel_last_multi_exit_btc_computable_exit_values_from_loop_multiple_exit_blocks(i32 %n) {181; CHECK-LABEL: define i32 @peel_last_multi_exit_btc_computable_exit_values_from_loop_multiple_exit_blocks(182; CHECK-SAME: i32 [[N:%.*]]) {183; CHECK-NEXT: [[ENTRY:.*]]:184; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]185; CHECK: [[LOOP_HEADER]]:186; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]187; CHECK-NEXT: [[EC_0:%.*]] = icmp eq i32 [[IV]], [[N]]188; CHECK-NEXT: br i1 [[EC_0]], label %[[EXIT_0:.*]], label %[[LOOP_LATCH]]189; CHECK: [[LOOP_LATCH]]:190; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[IV]], 16191; CHECK-NEXT: [[COND:%.*]] = select i1 [[C]], i32 10, i32 20192; CHECK-NEXT: call void @foo(i32 [[COND]])193; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1194; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], 17195; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_1:.*]], label %[[LOOP_HEADER]]196; CHECK: [[EXIT_0]]:197; CHECK-NEXT: [[RES_0:%.*]] = phi i32 [ [[IV]], %[[LOOP_HEADER]] ]198; CHECK-NEXT: ret i32 [[RES_0]]199; CHECK: [[EXIT_1]]:200; CHECK-NEXT: [[RES_1:%.*]] = phi i32 [ [[COND]], %[[LOOP_LATCH]] ]201; CHECK-NEXT: ret i32 [[RES_1]]202;203entry:204 br label %loop.header205 206loop.header:207 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]208 %ec.0 = icmp eq i32 %iv, %n209 br i1 %ec.0, label %exit.0, label %loop.latch210 211loop.latch:212 %c = icmp eq i32 %iv, 16213 %cond = select i1 %c, i32 10, i32 20214 call void @foo(i32 %cond)215 %iv.next = add i32 %iv, 1216 %ec = icmp eq i32 %iv.next, 17217 br i1 %ec, label %exit.1, label %loop.header218 219exit.0:220 %res.0 = phi i32 [ %iv, %loop.header ]221 ret i32 %res.0222 223exit.1:224 %res.1 = phi i32 [ %cond, %loop.latch ]225 ret i32 %res.1226}227 228define i64 @peel_last_btc_not_computable() {229; CHECK-LABEL: define i64 @peel_last_btc_not_computable() {230; CHECK-NEXT: [[ENTRY:.*]]:231; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]232; CHECK: [[LOOP_HEADER]]:233; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_PEEL:%.*]], %[[LOOP_LATCH:.*]] ]234; CHECK-NEXT: [[EC_0_PEEL:%.*]] = call i1 @cond()235; CHECK-NEXT: br i1 [[EC_0_PEEL]], label %[[THEN_1:.*]], label %[[EXIT:.*]]236; CHECK: [[THEN_1]]:237; CHECK-NEXT: call void @foo(i32 1)238; CHECK-NEXT: [[C_PEEL:%.*]] = icmp eq i64 [[IV_NEXT_LCSSA]], 7239; CHECK-NEXT: br i1 [[C_PEEL]], label %[[LOOP_LATCH]], label %[[THEN_2:.*]]240; CHECK: [[THEN_2]]:241; CHECK-NEXT: call void @foo(i32 2)242; CHECK-NEXT: br label %[[LOOP_LATCH]]243; CHECK: [[LOOP_LATCH]]:244; CHECK-NEXT: [[IV_NEXT_PEEL]] = add i64 [[IV_NEXT_LCSSA]], 1245; CHECK-NEXT: [[EXITCOND_PEEL:%.*]] = icmp ne i64 [[IV_NEXT_PEEL]], 8246; CHECK-NEXT: br i1 [[EXITCOND_PEEL]], label %[[LOOP_HEADER]], label %[[EXIT]]247; CHECK: [[EXIT]]:248; CHECK-NEXT: [[RES:%.*]] = phi i64 [ 1, %[[LOOP_LATCH]] ], [ 2, %[[LOOP_HEADER]] ]249; CHECK-NEXT: ret i64 [[RES]]250;251entry:252 br label %loop.header253 254loop.header:255 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]256 %ec.0 = call i1 @cond()257 br i1 %ec.0, label %then.1, label %exit258 259then.1:260 call void @foo(i32 1)261 %c = icmp eq i64 %iv, 7262 br i1 %c, label %loop.latch, label %then.2263 264then.2:265 call void @foo(i32 2)266 br label %loop.latch267 268loop.latch:269 %iv.next = add i64 %iv, 1270 %exitcond = icmp ne i64 %iv.next, 8271 br i1 %exitcond, label %loop.header, label %exit272 273exit:274 %res = phi i64 [ 1, %loop.latch ], [ 2, %loop.header ]275 ret i64 %res276}277 278define void @peel_exit_count_larger_than_btc(i32 %n) {279; CHECK-LABEL: define void @peel_exit_count_larger_than_btc(280; CHECK-SAME: i32 [[N:%.*]]) {281; CHECK-NEXT: [[ENTRY:.*]]:282; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]283; CHECK: [[LOOP_HEADER]]:284; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]285; CHECK-NEXT: [[EC_0:%.*]] = icmp eq i32 [[IV]], 10286; CHECK-NEXT: br i1 [[EC_0]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]287; CHECK: [[LOOP_LATCH]]:288; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[IV]], 9289; CHECK-NEXT: [[COND:%.*]] = select i1 [[C]], i32 10, i32 20290; CHECK-NEXT: call void @foo(i32 [[COND]])291; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1292; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], 17293; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]]294; CHECK: [[EXIT]]:295; CHECK-NEXT: ret void296;297entry:298 br label %loop.header299 300loop.header:301 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]302 %ec.0 = icmp eq i32 %iv, 10303 br i1 %ec.0, label %exit, label %loop.latch304 305loop.latch:306 %c = icmp eq i32 %iv, 9307 %cond = select i1 %c, i32 10, i32 20308 call void @foo(i32 %cond)309 %iv.next = add i32 %iv, 1310 %ec = icmp eq i32 %iv.next, 17311 br i1 %ec, label %exit, label %loop.header312 313exit:314 ret void315}316