brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.7 KiB · 5c9b2fa Raw
644 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 4define i64 @peel_single_block_loop_iv_step_1() {5; CHECK-LABEL: define i64 @peel_single_block_loop_iv_step_1() {6; CHECK-NEXT:  [[ENTRY:.*]]:7; CHECK-NEXT:    br label %[[LOOP:.*]]8; CHECK:       [[LOOP]]:9; CHECK-NEXT:    [[IV1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT1:%.*]], %[[LOOP]] ]10; CHECK-NEXT:    call void @foo(i32 20)11; CHECK-NEXT:    [[IV_NEXT1]] = add nuw nsw i64 [[IV1]], 112; CHECK-NEXT:    [[EC1:%.*]] = icmp ne i64 [[IV_NEXT1]], 6313; CHECK-NEXT:    br i1 [[EC1]], label %[[LOOP]], label %[[EXIT_PEEL_BEGIN:.*]], !llvm.loop [[LOOP0:![0-9]+]]14; CHECK:       [[EXIT_PEEL_BEGIN]]:15; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT1]], %[[LOOP]] ]16; CHECK-NEXT:    br label %[[LOOP_PEEL:.*]]17; CHECK:       [[LOOP_PEEL]]:18; CHECK-NEXT:    [[CMP18_NOT:%.*]] = icmp eq i64 [[IV]], 6319; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP18_NOT]], i32 10, i32 2020; CHECK-NEXT:    call void @foo(i32 [[COND]])21; CHECK-NEXT:    [[IV_NEXT:%.*]] = add i64 [[IV]], 122; CHECK-NEXT:    [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 6423; CHECK-NEXT:    br i1 [[EC]], label %[[EXIT_PEEL_NEXT:.*]], label %[[EXIT_PEEL_NEXT]]24; CHECK:       [[EXIT_PEEL_NEXT]]:25; CHECK-NEXT:    br label %[[LOOP_PEEL_NEXT:.*]]26; CHECK:       [[LOOP_PEEL_NEXT]]:27; CHECK-NEXT:    br label %[[EXIT:.*]]28; CHECK:       [[EXIT]]:29; CHECK-NEXT:    ret i64 [[IV]]30;31entry:32  br label %loop33 34loop:35  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]36  %cmp = icmp eq i64 %iv, 6337  %cond = select i1 %cmp, i32 10, i32 2038  call void @foo(i32 %cond)39  %iv.next = add i64 %iv, 140  %ec = icmp ne i64 %iv.next, 6441  br i1 %ec, label %loop, label %exit42 43exit:44  ret i64 %iv45}46 47; The predicate %cmp doesn't become known in all iterations after peeling.48define i64 @single_block_loop_iv_step_1_predicate_not_known_true_false_after_peeling() {49; CHECK-LABEL: define i64 @single_block_loop_iv_step_1_predicate_not_known_true_false_after_peeling() {50; CHECK-NEXT:  [[ENTRY:.*]]:51; CHECK-NEXT:    br label %[[LOOP:.*]]52; CHECK:       [[LOOP]]:53; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]54; CHECK-NEXT:    [[UREM:%.*]] = urem i64 [[IV]], 255; CHECK-NEXT:    [[CMP18_NOT:%.*]] = icmp eq i64 [[UREM]], 156; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP18_NOT]], i32 10, i32 2057; CHECK-NEXT:    call void @foo(i32 [[COND]])58; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 159; CHECK-NEXT:    [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 6460; CHECK-NEXT:    br i1 [[EC]], label %[[LOOP]], label %[[EXIT:.*]]61; CHECK:       [[EXIT]]:62; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LOOP]] ]63; CHECK-NEXT:    ret i64 [[IV_LCSSA]]64;65entry:66  br label %loop67 68loop:69  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]70  %urem = urem i64 %iv, 271  %cmp = icmp eq i64 %urem, 172  %cond = select i1 %cmp, i32 10, i32 2073  call void @foo(i32 %cond)74  %iv.next = add i64 %iv, 175  %ec = icmp ne i64 %iv.next, 6476  br i1 %ec, label %loop, label %exit77 78exit:79  ret i64 %iv80}81 82define i64 @peel_single_block_loop_iv_step_1_eq_pred() {83; CHECK-LABEL: define i64 @peel_single_block_loop_iv_step_1_eq_pred() {84; CHECK-NEXT:  [[ENTRY:.*]]:85; CHECK-NEXT:    br label %[[LOOP:.*]]86; CHECK:       [[LOOP]]:87; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_LCSSA:%.*]], %[[LOOP]] ]88; CHECK-NEXT:    call void @foo(i32 20)89; CHECK-NEXT:    [[IV_LCSSA]] = add nuw nsw i64 [[IV]], 190; CHECK-NEXT:    [[CMP_PEEL:%.*]] = icmp eq i64 [[IV_LCSSA]], 6391; CHECK-NEXT:    br i1 [[CMP_PEEL]], label %[[EXIT_PEEL_BEGIN:.*]], label %[[LOOP]], !llvm.loop [[LOOP2:![0-9]+]]92; CHECK:       [[EXIT_PEEL_BEGIN]]:93; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_LCSSA]], %[[LOOP]] ]94; CHECK-NEXT:    br label %[[LOOP_PEEL:.*]]95; CHECK:       [[LOOP_PEEL]]:96; CHECK-NEXT:    [[CMP_PEEL1:%.*]] = icmp eq i64 [[IV_NEXT_LCSSA]], 6397; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP_PEEL1]], i32 10, i32 2098; CHECK-NEXT:    call void @foo(i32 [[COND]])99; CHECK-NEXT:    [[IV_NEXT:%.*]] = add i64 [[IV_NEXT_LCSSA]], 1100; CHECK-NEXT:    [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 64101; CHECK-NEXT:    br i1 [[EC]], label %[[EXIT_PEEL_NEXT:.*]], label %[[EXIT_PEEL_NEXT]]102; CHECK:       [[EXIT_PEEL_NEXT]]:103; CHECK-NEXT:    br label %[[LOOP_PEEL_NEXT:.*]]104; CHECK:       [[LOOP_PEEL_NEXT]]:105; CHECK-NEXT:    br label %[[EXIT:.*]]106; CHECK:       [[EXIT]]:107; CHECK-NEXT:    ret i64 [[IV_NEXT_LCSSA]]108;109entry:110  br label %loop111 112loop:113  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]114  %cmp = icmp eq i64 %iv, 63115  %cond = select i1 %cmp, i32 10, i32 20116  call void @foo(i32 %cond)117  %iv.next = add i64 %iv, 1118  %ec = icmp eq i64 %iv.next, 64119  br i1 %ec, label %exit, label %loop120 121exit:122  ret i64 %iv123}124 125define i64 @peel_single_block_loop_iv_step_1_slt_pred() {126; CHECK-LABEL: define i64 @peel_single_block_loop_iv_step_1_slt_pred() {127; CHECK-NEXT:  [[ENTRY:.*]]:128; CHECK-NEXT:    br label %[[LOOP:.*]]129; CHECK:       [[LOOP]]:130; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]131; CHECK-NEXT:    [[CMP18_NOT:%.*]] = icmp eq i64 [[IV]], 63132; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP18_NOT]], i32 10, i32 20133; CHECK-NEXT:    call void @foo(i32 [[COND]])134; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1135; CHECK-NEXT:    [[EC:%.*]] = icmp slt i64 [[IV_NEXT]], 64136; CHECK-NEXT:    br i1 [[EC]], label %[[LOOP]], label %[[EXIT:.*]]137; CHECK:       [[EXIT]]:138; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LOOP]] ]139; CHECK-NEXT:    ret i64 [[IV_LCSSA]]140;141entry:142  br label %loop143 144loop:145  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]146  %cmp = icmp eq i64 %iv, 63147  %cond = select i1 %cmp, i32 10, i32 20148  call void @foo(i32 %cond)149  %iv.next = add i64 %iv, 1150  %ec = icmp slt i64 %iv.next, 64151  br i1 %ec, label %loop, label %exit152 153exit:154  ret i64 %iv155}156 157define i64 @peel_single_block_loop_iv_step_1_nested_loop() {158; CHECK-LABEL: define i64 @peel_single_block_loop_iv_step_1_nested_loop() {159; CHECK-NEXT:  [[ENTRY:.*]]:160; CHECK-NEXT:    br label %[[OUTER_HEADER:.*]]161; CHECK:       [[OUTER_HEADER]]:162; CHECK-NEXT:    [[OUTER_IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[OUTER_IV_NEXT:%.*]], %[[OUTER_LATCH:.*]] ]163; CHECK-NEXT:    br label %[[LOOP:.*]]164; CHECK:       [[LOOP]]:165; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[OUTER_HEADER]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]166; CHECK-NEXT:    call void @foo(i32 20)167; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1168; CHECK-NEXT:    [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 63169; CHECK-NEXT:    br i1 [[EC]], label %[[LOOP]], label %[[OUTER_LATCH_PEEL_BEGIN:.*]], !llvm.loop [[LOOP3:![0-9]+]]170; CHECK:       [[OUTER_LATCH_PEEL_BEGIN]]:171; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], %[[LOOP]] ]172; CHECK-NEXT:    br label %[[LOOP_PEEL:.*]]173; CHECK:       [[LOOP_PEEL]]:174; CHECK-NEXT:    [[CMP_PEEL:%.*]] = icmp eq i64 [[IV_NEXT_LCSSA]], 63175; CHECK-NEXT:    [[COND_PEEL:%.*]] = select i1 [[CMP_PEEL]], i32 10, i32 20176; CHECK-NEXT:    call void @foo(i32 [[COND_PEEL]])177; CHECK-NEXT:    [[IV_NEXT_PEEL:%.*]] = add i64 [[IV_NEXT_LCSSA]], 1178; CHECK-NEXT:    [[EC_PEEL:%.*]] = icmp ne i64 [[IV_NEXT_PEEL]], 64179; CHECK-NEXT:    br i1 [[EC_PEEL]], label %[[OUTER_LATCH_PEEL_NEXT:.*]], label %[[OUTER_LATCH_PEEL_NEXT]]180; CHECK:       [[OUTER_LATCH_PEEL_NEXT]]:181; CHECK-NEXT:    br label %[[LOOP_PEEL_NEXT:.*]]182; CHECK:       [[LOOP_PEEL_NEXT]]:183; CHECK-NEXT:    br label %[[OUTER_LATCH]]184; CHECK:       [[OUTER_LATCH]]:185; CHECK-NEXT:    call void @foo(i32 1)186; CHECK-NEXT:    [[OUTER_IV_NEXT]] = add i64 [[OUTER_IV]], 1187; CHECK-NEXT:    [[OUTER_EC:%.*]] = icmp ne i64 [[OUTER_IV_NEXT]], 100188; CHECK-NEXT:    br i1 [[OUTER_EC]], label %[[EXIT:.*]], label %[[OUTER_HEADER]]189; CHECK:       [[EXIT]]:190; CHECK-NEXT:    [[IV_LCSSA_LCSSA:%.*]] = phi i64 [ [[IV_NEXT_LCSSA]], %[[OUTER_LATCH]] ]191; CHECK-NEXT:    ret i64 [[IV_LCSSA_LCSSA]]192;193entry:194  br label %outer.header195 196outer.header:197  %outer.iv = phi i64 [ 0, %entry ], [ %outer.iv.next, %outer.latch ]198  br label %loop199 200loop:201  %iv = phi i64 [ 0, %outer.header ], [ %iv.next, %loop ]202  %cmp = icmp eq i64 %iv, 63203  %cond = select i1 %cmp, i32 10, i32 20204  call void @foo(i32 %cond)205  %iv.next = add i64 %iv, 1206  %ec = icmp ne i64 %iv.next, 64207  br i1 %ec, label %loop, label %outer.latch208 209outer.latch:210  call void @foo(i32 1)211  %outer.iv.next = add i64 %outer.iv, 1212  %outer.ec = icmp ne i64 %outer.iv.next, 100213  br i1 %outer.ec, label %exit, label %outer.header214 215exit:216  ret i64 %iv217}218 219define i64 @peel_multi_block_loop_iv_step_1() {220; CHECK-LABEL: define i64 @peel_multi_block_loop_iv_step_1() {221; CHECK-NEXT:  [[ENTRY:.*]]:222; CHECK-NEXT:    br label %[[LOOP:.*]]223; CHECK:       [[LOOP]]:224; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ]225; CHECK-NEXT:    call void @foo(i32 20)226; CHECK-NEXT:    [[C:%.*]] = call i1 @cond()227; CHECK-NEXT:    br i1 [[C]], label %[[THEN:.*]], label %[[LATCH]]228; CHECK:       [[THEN]]:229; CHECK-NEXT:    call void @foo(i32 20)230; CHECK-NEXT:    br label %[[LATCH]]231; CHECK:       [[LATCH]]:232; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1233; CHECK-NEXT:    [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 63234; CHECK-NEXT:    br i1 [[EC]], label %[[LOOP]], label %[[EXIT_PEEL_BEGIN:.*]], !llvm.loop [[LOOP4:![0-9]+]]235; CHECK:       [[EXIT_PEEL_BEGIN]]:236; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], %[[LATCH]] ]237; CHECK-NEXT:    br label %[[LOOP_PEEL:.*]]238; CHECK:       [[LOOP_PEEL]]:239; CHECK-NEXT:    [[CMP_PEEL:%.*]] = icmp eq i64 [[IV_NEXT_LCSSA]], 63240; CHECK-NEXT:    [[COND_PEEL:%.*]] = select i1 [[CMP_PEEL]], i32 10, i32 20241; CHECK-NEXT:    call void @foo(i32 [[COND_PEEL]])242; CHECK-NEXT:    [[C_PEEL:%.*]] = call i1 @cond()243; CHECK-NEXT:    br i1 [[C_PEEL]], label %[[THEN_PEEL:.*]], label %[[LATCH_PEEL:.*]]244; CHECK:       [[THEN_PEEL]]:245; CHECK-NEXT:    call void @foo(i32 [[COND_PEEL]])246; CHECK-NEXT:    br label %[[LATCH_PEEL]]247; CHECK:       [[LATCH_PEEL]]:248; CHECK-NEXT:    [[IV_NEXT_PEEL:%.*]] = add i64 [[IV_NEXT_LCSSA]], 1249; CHECK-NEXT:    [[EC_PEEL:%.*]] = icmp ne i64 [[IV_NEXT_PEEL]], 64250; CHECK-NEXT:    br i1 [[EC_PEEL]], label %[[EXIT_PEEL_NEXT:.*]], label %[[EXIT_PEEL_NEXT]]251; CHECK:       [[EXIT_PEEL_NEXT]]:252; CHECK-NEXT:    br label %[[LOOP_PEEL_NEXT:.*]]253; CHECK:       [[LOOP_PEEL_NEXT]]:254; CHECK-NEXT:    br label %[[EXIT:.*]]255; CHECK:       [[EXIT]]:256; CHECK-NEXT:    ret i64 [[IV_NEXT_LCSSA]]257;258entry:259  br label %loop260 261loop:262  %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]263  %cmp = icmp eq i64 %iv, 63264  %cond = select i1 %cmp, i32 10, i32 20265  call void @foo(i32 %cond)266  %c = call i1 @cond()267  br i1 %c, label %then, label %latch268 269then:270  call void @foo(i32 %cond)271  br label %latch272 273latch:274  %iv.next = add i64 %iv, 1275  %ec = icmp ne i64 %iv.next, 64276  br i1 %ec, label %loop, label %exit277 278exit:279  ret i64 %iv280}281 282define i64 @peel_multi_exit_loop_iv_step_1() {283; CHECK-LABEL: define i64 @peel_multi_exit_loop_iv_step_1() {284; CHECK-NEXT:  [[ENTRY:.*]]:285; CHECK-NEXT:    br label %[[LOOP:.*]]286; CHECK:       [[LOOP]]:287; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ]288; CHECK-NEXT:    [[CMP18_NOT:%.*]] = icmp eq i64 [[IV]], 63289; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP18_NOT]], i32 10, i32 20290; CHECK-NEXT:    call void @foo(i32 [[COND]])291; CHECK-NEXT:    [[C:%.*]] = call i1 @cond()292; CHECK-NEXT:    br i1 [[C]], label %[[EXIT:.*]], label %[[LATCH]]293; CHECK:       [[LATCH]]:294; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1295; CHECK-NEXT:    [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 64296; CHECK-NEXT:    br i1 [[EC]], label %[[LOOP]], label %[[EXIT]]297; CHECK:       [[EXIT]]:298; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LATCH]] ], [ [[IV]], %[[LOOP]] ]299; CHECK-NEXT:    ret i64 [[IV_LCSSA]]300;301entry:302  br label %loop303 304loop:305  %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]306  %cmp = icmp eq i64 %iv, 63307  %cond = select i1 %cmp, i32 10, i32 20308  call void @foo(i32 %cond)309  %c = call i1 @cond()310  br i1 %c, label %exit, label %latch311 312latch:313  %iv.next = add i64 %iv, 1314  %ec = icmp ne i64 %iv.next, 64315  br i1 %ec, label %loop, label %exit316 317exit:318  ret i64 %iv319}320 321define i64 @peel_single_block_loop_iv_step_1_btc_0() {322; CHECK-LABEL: define i64 @peel_single_block_loop_iv_step_1_btc_0() {323; CHECK-NEXT:  [[ENTRY:.*]]:324; CHECK-NEXT:    br label %[[LOOP:.*]]325; CHECK:       [[LOOP]]:326; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]327; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[IV]], 0328; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 10, i32 20329; CHECK-NEXT:    call void @foo(i32 [[COND]])330; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1331; CHECK-NEXT:    [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 1332; CHECK-NEXT:    br i1 [[EC]], label %[[LOOP]], label %[[EXIT:.*]]333; CHECK:       [[EXIT]]:334; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LOOP]] ]335; CHECK-NEXT:    ret i64 [[IV_LCSSA]]336;337entry:338  br label %loop339 340loop:341  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]342  %cmp = icmp eq i64 %iv, 0343  %cond = select i1 %cmp, i32 10, i32 20344  call void @foo(i32 %cond)345  %iv.next = add i64 %iv, 1346  %ec = icmp ne i64 %iv.next, 1347  br i1 %ec, label %loop, label %exit348 349exit:350  ret i64 %iv351}352 353define i64 @peel_single_block_loop_iv_step_1_btc_1() {354; CHECK-LABEL: define i64 @peel_single_block_loop_iv_step_1_btc_1() {355; CHECK-NEXT:  [[ENTRY:.*]]:356; CHECK-NEXT:    br label %[[LOOP:.*]]357; CHECK:       [[LOOP]]:358; CHECK-NEXT:    [[IV1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT1:%.*]], %[[LOOP]] ]359; CHECK-NEXT:    call void @foo(i32 20)360; CHECK-NEXT:    [[IV_NEXT1]] = add nuw nsw i64 [[IV1]], 1361; CHECK-NEXT:    br i1 false, label %[[LOOP]], label %[[EXIT_PEEL_BEGIN:.*]], !llvm.loop [[LOOP5:![0-9]+]]362; CHECK:       [[EXIT_PEEL_BEGIN]]:363; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT1]], %[[LOOP]] ]364; CHECK-NEXT:    br label %[[LOOP_PEEL:.*]]365; CHECK:       [[LOOP_PEEL]]:366; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[IV]], 1367; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 10, i32 20368; CHECK-NEXT:    call void @foo(i32 [[COND]])369; CHECK-NEXT:    [[IV_NEXT:%.*]] = add i64 [[IV]], 1370; CHECK-NEXT:    [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 2371; CHECK-NEXT:    br i1 [[EC]], label %[[EXIT_PEEL_NEXT:.*]], label %[[EXIT_PEEL_NEXT]]372; CHECK:       [[EXIT_PEEL_NEXT]]:373; CHECK-NEXT:    br label %[[LOOP_PEEL_NEXT:.*]]374; CHECK:       [[LOOP_PEEL_NEXT]]:375; CHECK-NEXT:    br label %[[EXIT:.*]]376; CHECK:       [[EXIT]]:377; CHECK-NEXT:    ret i64 [[IV]]378;379entry:380  br label %loop381 382loop:383  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]384  %cmp = icmp eq i64 %iv, 1385  %cond = select i1 %cmp, i32 10, i32 20386  call void @foo(i32 %cond)387  %iv.next = add i64 %iv, 1388  %ec = icmp ne i64 %iv.next, 2389  br i1 %ec, label %loop, label %exit390 391exit:392  ret i64 %iv393}394 395define i64 @peel_single_block_loop_iv_step_neg_1() {396; CHECK-LABEL: define i64 @peel_single_block_loop_iv_step_neg_1() {397; CHECK-NEXT:  [[ENTRY:.*]]:398; CHECK-NEXT:    br label %[[LOOP:.*]]399; CHECK:       [[LOOP]]:400; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 64, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]401; CHECK-NEXT:    [[CMP18_NOT:%.*]] = icmp eq i64 [[IV]], 1402; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP18_NOT]], i32 10, i32 20403; CHECK-NEXT:    call void @foo(i32 [[COND]])404; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], -1405; CHECK-NEXT:    [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 0406; CHECK-NEXT:    br i1 [[EC]], label %[[LOOP]], label %[[EXIT:.*]]407; CHECK:       [[EXIT]]:408; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LOOP]] ]409; CHECK-NEXT:    ret i64 [[IV_LCSSA]]410;411entry:412  br label %loop413 414loop:415  %iv = phi i64 [ 64, %entry ], [ %iv.next, %loop ]416  %cmp = icmp eq i64 %iv, 1417  %cond = select i1 %cmp, i32 10, i32 20418  call void @foo(i32 %cond)419  %iv.next = add i64 %iv, -1420  %ec = icmp ne i64 %iv.next, 0421  br i1 %ec, label %loop, label %exit422 423exit:424  ret i64 %iv425}426 427define i64 @peel_single_block_loop_iv_step_2() {428; CHECK-LABEL: define i64 @peel_single_block_loop_iv_step_2() {429; CHECK-NEXT:  [[ENTRY:.*]]:430; CHECK-NEXT:    br label %[[LOOP:.*]]431; CHECK:       [[LOOP]]:432; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]433; CHECK-NEXT:    [[CMP18_NOT:%.*]] = icmp eq i64 [[IV]], 62434; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP18_NOT]], i32 10, i32 20435; CHECK-NEXT:    call void @foo(i32 [[COND]])436; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 2437; CHECK-NEXT:    [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 64438; CHECK-NEXT:    br i1 [[EC]], label %[[LOOP]], label %[[EXIT:.*]]439; CHECK:       [[EXIT]]:440; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LOOP]] ]441; CHECK-NEXT:    ret i64 [[IV_LCSSA]]442;443entry:444  br label %loop445 446loop:447  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]448  %cmp = icmp eq i64 %iv, 62449  %cond = select i1 %cmp, i32 10, i32 20450  call void @foo(i32 %cond)451  %iv.next = add i64 %iv, 2452  %ec = icmp ne i64 %iv.next, 64453  br i1 %ec, label %loop, label %exit454 455exit:456  ret i64 %iv457}458 459define i32 @peel_loop_with_branch_and_phi_uses(ptr %x, i1 %c) {460; CHECK-LABEL: define i32 @peel_loop_with_branch_and_phi_uses(461; CHECK-SAME: ptr [[X:%.*]], i1 [[C:%.*]]) {462; CHECK-NEXT:  [[ENTRY:.*]]:463; CHECK-NEXT:    br i1 [[C]], label %[[LOOP_HEADER_PREHEADER:.*]], label %[[EXIT:.*]]464; CHECK:       [[LOOP_HEADER_PREHEADER]]:465; CHECK-NEXT:    br label %[[LOOP_HEADER:.*]]466; CHECK:       [[LOOP_HEADER]]:467; CHECK-NEXT:    [[IV1:%.*]] = phi i32 [ [[IV_NEXT1:%.*]], %[[LOOP_LATCH:.*]] ], [ 0, %[[LOOP_HEADER_PREHEADER]] ]468; CHECK-NEXT:    [[RED1:%.*]] = phi i32 [ [[ADD1:%.*]], %[[LOOP_LATCH]] ], [ 0, %[[LOOP_HEADER_PREHEADER]] ]469; CHECK-NEXT:    br i1 false, label %[[IF_THEN:.*]], label %[[LOOP_LATCH]]470; CHECK:       [[IF_THEN]]:471; CHECK-NEXT:    tail call void @foo(i32 10)472; CHECK-NEXT:    br label %[[LOOP_LATCH]]473; CHECK:       [[LOOP_LATCH]]:474; CHECK-NEXT:    [[GEP_X1:%.*]] = getelementptr inbounds nuw i32, ptr [[X]], i32 [[IV1]]475; CHECK-NEXT:    [[L1:%.*]] = load i32, ptr [[GEP_X1]], align 4476; CHECK-NEXT:    [[ADD1]] = add nsw i32 [[L1]], [[RED1]]477; CHECK-NEXT:    [[IV_NEXT1]] = add nuw nsw i32 [[IV1]], 1478; CHECK-NEXT:    [[EC1:%.*]] = icmp ne i32 [[IV_NEXT1]], 99479; CHECK-NEXT:    br i1 [[EC1]], label %[[LOOP_HEADER]], label %[[LOOPEXIT_PEEL_BEGIN:.*]], !llvm.loop [[LOOP6:![0-9]+]]480; CHECK:       [[LOOPEXIT_PEEL_BEGIN]]:481; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT1]], %[[LOOP_LATCH]] ]482; CHECK-NEXT:    [[RED:%.*]] = phi i32 [ [[ADD1]], %[[LOOP_LATCH]] ]483; CHECK-NEXT:    br label %[[LOOP_HEADER_PEEL:.*]]484; CHECK:       [[LOOP_HEADER_PEEL]]:485; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[IV]], 99486; CHECK-NEXT:    br i1 [[CMP1]], label %[[IF_THEN_PEEL:.*]], label %[[LOOP_LATCH_PEEL:.*]]487; CHECK:       [[IF_THEN_PEEL]]:488; CHECK-NEXT:    tail call void @foo(i32 10)489; CHECK-NEXT:    br label %[[LOOP_LATCH_PEEL]]490; CHECK:       [[LOOP_LATCH_PEEL]]:491; CHECK-NEXT:    [[GEP_X:%.*]] = getelementptr inbounds nuw i32, ptr [[X]], i32 [[IV]]492; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[GEP_X]], align 4493; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[L]], [[RED]]494; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i32 [[IV]], 1495; CHECK-NEXT:    [[EC:%.*]] = icmp ne i32 [[IV_NEXT]], 100496; CHECK-NEXT:    br i1 [[EC]], label %[[LOOPEXIT_PEEL_NEXT:.*]], label %[[LOOPEXIT_PEEL_NEXT]]497; CHECK:       [[LOOPEXIT_PEEL_NEXT]]:498; CHECK-NEXT:    br label %[[LOOP_HEADER_PEEL_NEXT:.*]]499; CHECK:       [[LOOP_HEADER_PEEL_NEXT]]:500; CHECK-NEXT:    br label %[[LOOPEXIT:.*]]501; CHECK:       [[LOOPEXIT]]:502; CHECK-NEXT:    br label %[[EXIT]]503; CHECK:       [[EXIT]]:504; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[ADD]], %[[LOOPEXIT]] ]505; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]506;507entry:508  br i1 %c, label %loop.header, label %exit509 510loop.header:511  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]512  %red = phi i32 [ 0, %entry ], [ %add, %loop.latch ]513  %cmp1 = icmp eq i32 %iv, 99514  br i1 %cmp1, label %if.then, label %loop.latch515 516if.then:517  tail call void @foo(i32 10)518  br label %loop.latch519 520loop.latch:521  %gep.x = getelementptr inbounds nuw i32, ptr %x, i32 %iv522  %l = load i32, ptr %gep.x, align 4523  %add = add nsw i32 %l, %red524  %iv.next = add nuw nsw i32 %iv, 1525  %ec = icmp ne i32 %iv.next, 100526  br i1 %ec, label %loop.header, label %loopexit527 528loopexit:529  %add.lcssa = phi i32 [ %add, %loop.latch ]530  br label %exit531 532exit:533  %sum.0.lcssa = phi i32 [ 0, %entry ], [ %add.lcssa, %loopexit ]534  ret i32 %sum.0.lcssa535}536 537define i64 @peel_multi_exit_multi_latch_loop_iv_step_1(i64 %N) {538; CHECK-LABEL: define i64 @peel_multi_exit_multi_latch_loop_iv_step_1(539; CHECK-SAME: i64 [[N:%.*]]) {540; CHECK-NEXT:  [[ENTRY:.*]]:541; CHECK-NEXT:    br label %[[LOOP:.*]]542; CHECK:       [[LOOP]]:543; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_BE:%.*]], %[[LOOP_BACKEDGE:.*]] ]544; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[IV]], 63545; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 10, i32 20546; CHECK-NEXT:    call void @foo(i32 [[COND]])547; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i64 [[IV]], [[N]]548; CHECK-NEXT:    br i1 [[C_1]], label %[[THEN:.*]], label %[[ELSE:.*]]549; CHECK:       [[THEN]]:550; CHECK-NEXT:    call void @foo(i32 20)551; CHECK-NEXT:    [[IV_NEXT_1:%.*]] = add i64 [[IV]], 1552; CHECK-NEXT:    [[EC_1:%.*]] = icmp ne i64 [[IV_NEXT_1]], 64553; CHECK-NEXT:    br i1 [[EC_1]], label %[[EXIT:.*]], label %[[LOOP_BACKEDGE]]554; CHECK:       [[LOOP_BACKEDGE]]:555; CHECK-NEXT:    [[IV_BE]] = phi i64 [ [[IV_NEXT_1]], %[[THEN]] ], [ [[IV_NEXT_2:%.*]], %[[ELSE]] ]556; CHECK-NEXT:    br label %[[LOOP]]557; CHECK:       [[ELSE]]:558; CHECK-NEXT:    call void @foo(i32 10)559; CHECK-NEXT:    [[IV_NEXT_2]] = add i64 [[IV]], 1560; CHECK-NEXT:    [[EC_2:%.*]] = icmp ne i64 [[IV_NEXT_2]], 64561; CHECK-NEXT:    br i1 [[EC_2]], label %[[LOOP_BACKEDGE]], label %[[EXIT]]562; CHECK:       [[EXIT]]:563; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[ELSE]] ], [ [[IV]], %[[THEN]] ]564; CHECK-NEXT:    ret i64 [[IV_LCSSA]]565;566entry:567  br label %loop568 569loop:570  %iv = phi i64 [ 0, %entry ], [ %iv.next.1, %then ], [ %iv.next.2, %else ]571  %cmp = icmp eq i64 %iv, 63572  %cond = select i1 %cmp, i32 10, i32 20573  call void @foo(i32 %cond)574  %c.1 = icmp eq i64 %iv, %N575  br i1 %c.1, label %then, label %else576 577then:578  call void @foo(i32 20)579  %iv.next.1 = add i64 %iv, 1580  %ec.1 = icmp ne i64 %iv.next.1, 64581  br i1 %ec.1, label %exit, label %loop582 583else:584  call void @foo(i32 10)585  %iv.next.2 = add i64 %iv, 1586  %ec.2 = icmp ne i64 %iv.next.2, 64587  br i1 %ec.2, label %loop, label %exit588 589exit:590  ret i64 %iv591}592 593; Test for https://github.com/llvm/llvm-project/issues/140444.594define void @exit_condition_has_other_loop_users() {595; CHECK-LABEL: define void @exit_condition_has_other_loop_users() {596; CHECK-NEXT:  [[ENTRY:.*]]:597; CHECK-NEXT:    br label %[[LOOP_HEADER:.*]]598; CHECK:       [[LOOP_HEADER]]:599; CHECK-NEXT:    [[IV_NEXT_LCSSA:%.*]] = phi i16 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_PEEL:%.*]], %[[LOOP_LATCH:.*]] ]600; CHECK-NEXT:    [[IV_NEXT_PEEL]] = add i16 [[IV_NEXT_LCSSA]], 1601; CHECK-NEXT:    [[EC_PEEL:%.*]] = icmp eq i16 [[IV_NEXT_LCSSA]], 100602; CHECK-NEXT:    br i1 [[EC_PEEL]], label %[[LOOP_LATCH]], label %[[THEN:.*]]603; CHECK:       [[THEN]]:604; CHECK-NEXT:    call void @foo(i32 10)605; CHECK-NEXT:    br label %[[LOOP_LATCH]]606; CHECK:       [[LOOP_LATCH]]:607; CHECK-NEXT:    call void @foo(i32 20)608; CHECK-NEXT:    br i1 [[EC_PEEL]], label %[[EXIT:.*]], label %[[LOOP_HEADER]]609; CHECK:       [[EXIT]]:610; CHECK-NEXT:    ret void611;612entry:613  br label %loop.header614 615loop.header:616  %iv = phi i16 [ 0, %entry ], [ %iv.next, %loop.latch ]617  %iv.next = add i16 %iv, 1618  %ec = icmp eq i16 %iv, 100619  br i1 %ec, label %loop.latch, label %then620 621then:622  call void @foo(i32 10)623  br label %loop.latch624 625loop.latch:626  call void @foo(i32 20)627  br i1 %ec, label %exit, label %loop.header628 629exit:630  ret void631}632 633declare void @foo(i32)634declare i1 @cond()635;.636; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]]}637; CHECK: [[META1]] = !{!"llvm.loop.peeled.count", i32 1}638; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[META1]]}639; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META1]]}640; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]]}641; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META1]]}642; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META1]]}643;.644