brintos

brintos / llvm-project-archived public Read only

0
0
Text · 86.1 KiB · 4d08645 Raw
2064 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -S -passes=loop-unroll -unroll-peel-max-count=4 -verify-dom-info | FileCheck %s3 4declare void @f1()5declare void @f2()6declare void @f3(i32)7 8; Check that we can peel off iterations that make conditions true.9define void @test1(i32 %k) {10; CHECK-LABEL: @test1(11; CHECK-NEXT:  for.body.lr.ph:12; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]13; CHECK:       for.body.peel.begin:14; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]15; CHECK:       for.body.peel:16; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp ult i32 0, 217; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_ELSE_PEEL:%.*]]18; CHECK:       if.else.peel:19; CHECK-NEXT:    call void @f2()20; CHECK-NEXT:    br label [[FOR_INC_PEEL:%.*]]21; CHECK:       if.then.peel:22; CHECK-NEXT:    call void @f1()23; CHECK-NEXT:    br label [[FOR_INC_PEEL]]24; CHECK:       for.inc.peel:25; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nsw i32 0, 126; CHECK-NEXT:    [[CMP_PEEL:%.*]] = icmp slt i32 [[INC_PEEL]], [[K:%.*]]27; CHECK-NEXT:    br i1 [[CMP_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_END:%[^,]*]]28; Verify that MD_loop metadata is dropped.29; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}30; CHECK:       for.body.peel.next:31; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]32; CHECK:       for.body.peel2:33; CHECK-NEXT:    [[CMP1_PEEL3:%.*]] = icmp ult i32 [[INC_PEEL]], 234; CHECK-NEXT:    br i1 [[CMP1_PEEL3]], label [[IF_THEN_PEEL5:%.*]], label [[IF_ELSE_PEEL4:%.*]]35; CHECK:       if.else.peel4:36; CHECK-NEXT:    call void @f2()37; CHECK-NEXT:    br label [[FOR_INC_PEEL6:%.*]]38; CHECK:       if.then.peel5:39; CHECK-NEXT:    call void @f1()40; CHECK-NEXT:    br label [[FOR_INC_PEEL6]]41; CHECK:       for.inc.peel6:42; CHECK-NEXT:    [[INC_PEEL7:%.*]] = add nsw i32 [[INC_PEEL]], 143; CHECK-NEXT:    [[CMP_PEEL8:%.*]] = icmp slt i32 [[INC_PEEL7]], [[K]]44; CHECK-NEXT:    br i1 [[CMP_PEEL8]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_END]]45; Verify that MD_loop metadata is dropped.46; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}47; CHECK:       for.body.peel.next1:48; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT9:%.*]]49; CHECK:       for.body.peel.next9:50; CHECK-NEXT:    br label [[FOR_BODY_LR_PH_PEEL_NEWPH:%.*]]51; CHECK:       for.body.lr.ph.peel.newph:52; CHECK-NEXT:    br label [[FOR_BODY:%.*]]53; CHECK:       for.body:54; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ [[INC_PEEL7]], [[FOR_BODY_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]55; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]56; CHECK:       if.then:57; CHECK-NEXT:    call void @f1()58; CHECK-NEXT:    br label [[FOR_INC]]59; CHECK:       if.else:60; CHECK-NEXT:    call void @f2()61; CHECK-NEXT:    br label [[FOR_INC]]62; CHECK:       for.inc:63; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_05]], 164; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K]]65; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop !{{.*}}66; CHECK:       for.end.loopexit:67; CHECK-NEXT:    br label [[FOR_END]]68; CHECK:       for.end:69; CHECK-NEXT:    ret void70;71for.body.lr.ph:72  br label %for.body73 74for.body:75  %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]76  %cmp1 = icmp ult i32 %i.05, 277  br i1 %cmp1, label %if.then, label %if.else78 79if.then:80  call void @f1()81  br label %for.inc82 83if.else:84  call void @f2()85  br label %for.inc86 87for.inc:88  %inc = add nsw i32 %i.05, 189  %cmp = icmp slt i32 %inc, %k90  br i1 %cmp, label %for.body, label %for.end, !llvm.loop !191 92for.end:93  ret void94}95 96!1 = distinct !{!1}97 98; Check we peel off the maximum number of iterations that make conditions true.99define void @test2(i32 %k) {100; CHECK-LABEL: @test2(101; CHECK-NEXT:  for.body.lr.ph:102; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]103; CHECK:       for.body.peel.begin:104; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]105; CHECK:       for.body.peel:106; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp ult i32 0, 2107; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_ELSE_PEEL:%.*]]108; CHECK:       if.else.peel:109; CHECK-NEXT:    call void @f2()110; CHECK-NEXT:    br label [[IF2_PEEL:%.*]]111; CHECK:       if.then.peel:112; CHECK-NEXT:    call void @f1()113; CHECK-NEXT:    br label [[IF2_PEEL]]114; CHECK:       if2.peel:115; CHECK-NEXT:    [[CMP2_PEEL:%.*]] = icmp ult i32 0, 4116; CHECK-NEXT:    br i1 [[CMP2_PEEL]], label [[IF_THEN2_PEEL:%.*]], label [[FOR_INC_PEEL:%.*]]117; CHECK:       if.then2.peel:118; CHECK-NEXT:    call void @f1()119; CHECK-NEXT:    br label [[FOR_INC_PEEL]]120; CHECK:       for.inc.peel:121; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nsw i32 0, 1122; CHECK-NEXT:    [[CMP_PEEL:%.*]] = icmp slt i32 [[INC_PEEL]], [[K:%.*]]123; CHECK-NEXT:    br i1 [[CMP_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_END:%[^,]*]]124; Verify that MD_loop metadata is dropped.125; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}126; CHECK:       for.body.peel.next:127; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]128; CHECK:       for.body.peel2:129; CHECK-NEXT:    [[CMP1_PEEL3:%.*]] = icmp ult i32 [[INC_PEEL]], 2130; CHECK-NEXT:    br i1 [[CMP1_PEEL3]], label [[IF_THEN_PEEL5:%.*]], label [[IF_ELSE_PEEL4:%.*]]131; CHECK:       if.else.peel4:132; CHECK-NEXT:    call void @f2()133; CHECK-NEXT:    br label [[IF2_PEEL6:%.*]]134; CHECK:       if.then.peel5:135; CHECK-NEXT:    call void @f1()136; CHECK-NEXT:    br label [[IF2_PEEL6]]137; CHECK:       if2.peel6:138; CHECK-NEXT:    [[CMP2_PEEL7:%.*]] = icmp ult i32 [[INC_PEEL]], 4139; CHECK-NEXT:    br i1 [[CMP2_PEEL7]], label [[IF_THEN2_PEEL8:%.*]], label [[FOR_INC_PEEL9:%.*]]140; CHECK:       if.then2.peel8:141; CHECK-NEXT:    call void @f1()142; CHECK-NEXT:    br label [[FOR_INC_PEEL9]]143; CHECK:       for.inc.peel9:144; CHECK-NEXT:    [[INC_PEEL10:%.*]] = add nsw i32 [[INC_PEEL]], 1145; CHECK-NEXT:    [[CMP_PEEL11:%.*]] = icmp slt i32 [[INC_PEEL10]], [[K]]146; CHECK-NEXT:    br i1 [[CMP_PEEL11]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_END]]147; Verify that MD_loop metadata is dropped.148; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}149; CHECK:       for.body.peel.next1:150; CHECK-NEXT:    br label [[FOR_BODY_PEEL13:%.*]]151; CHECK:       for.body.peel13:152; CHECK-NEXT:    [[CMP1_PEEL14:%.*]] = icmp ult i32 [[INC_PEEL10]], 2153; CHECK-NEXT:    br i1 [[CMP1_PEEL14]], label [[IF_THEN_PEEL16:%.*]], label [[IF_ELSE_PEEL15:%.*]]154; CHECK:       if.else.peel15:155; CHECK-NEXT:    call void @f2()156; CHECK-NEXT:    br label [[IF2_PEEL17:%.*]]157; CHECK:       if.then.peel16:158; CHECK-NEXT:    call void @f1()159; CHECK-NEXT:    br label [[IF2_PEEL17]]160; CHECK:       if2.peel17:161; CHECK-NEXT:    [[CMP2_PEEL18:%.*]] = icmp ult i32 [[INC_PEEL10]], 4162; CHECK-NEXT:    br i1 [[CMP2_PEEL18]], label [[IF_THEN2_PEEL19:%.*]], label [[FOR_INC_PEEL20:%.*]]163; CHECK:       if.then2.peel19:164; CHECK-NEXT:    call void @f1()165; CHECK-NEXT:    br label [[FOR_INC_PEEL20]]166; CHECK:       for.inc.peel20:167; CHECK-NEXT:    [[INC_PEEL21:%.*]] = add nsw i32 [[INC_PEEL10]], 1168; CHECK-NEXT:    [[CMP_PEEL22:%.*]] = icmp slt i32 [[INC_PEEL21]], [[K]]169; CHECK-NEXT:    br i1 [[CMP_PEEL22]], label [[FOR_BODY_PEEL_NEXT12:%.*]], label [[FOR_END]]170; Verify that MD_loop metadata is dropped.171; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}172; CHECK:       for.body.peel.next12:173; CHECK-NEXT:    br label [[FOR_BODY_PEEL24:%.*]]174; CHECK:       for.body.peel24:175; CHECK-NEXT:    [[CMP1_PEEL25:%.*]] = icmp ult i32 [[INC_PEEL21]], 2176; CHECK-NEXT:    br i1 [[CMP1_PEEL25]], label [[IF_THEN_PEEL27:%.*]], label [[IF_ELSE_PEEL26:%.*]]177; CHECK:       if.else.peel26:178; CHECK-NEXT:    call void @f2()179; CHECK-NEXT:    br label [[IF2_PEEL28:%.*]]180; CHECK:       if.then.peel27:181; CHECK-NEXT:    call void @f1()182; CHECK-NEXT:    br label [[IF2_PEEL28]]183; CHECK:       if2.peel28:184; CHECK-NEXT:    [[CMP2_PEEL29:%.*]] = icmp ult i32 [[INC_PEEL21]], 4185; CHECK-NEXT:    br i1 [[CMP2_PEEL29]], label [[IF_THEN2_PEEL30:%.*]], label [[FOR_INC_PEEL31:%.*]]186; CHECK:       if.then2.peel30:187; CHECK-NEXT:    call void @f1()188; CHECK-NEXT:    br label [[FOR_INC_PEEL31]]189; CHECK:       for.inc.peel31:190; CHECK-NEXT:    [[INC_PEEL32:%.*]] = add nsw i32 [[INC_PEEL21]], 1191; CHECK-NEXT:    [[CMP_PEEL33:%.*]] = icmp slt i32 [[INC_PEEL32]], [[K]]192; CHECK-NEXT:    br i1 [[CMP_PEEL33]], label [[FOR_BODY_PEEL_NEXT23:%.*]], label [[FOR_END]]193; Verify that MD_loop metadata is dropped.194; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}195; CHECK:       for.body.peel.next23:196; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT34:%.*]]197; CHECK:       for.body.peel.next34:198; CHECK-NEXT:    br label [[FOR_BODY_LR_PH_PEEL_NEWPH:%.*]]199; CHECK:       for.body.lr.ph.peel.newph:200; CHECK-NEXT:    br label [[FOR_BODY:%.*]]201; CHECK:       for.body:202; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ [[INC_PEEL32]], [[FOR_BODY_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]203; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]204; CHECK:       if.then:205; CHECK-NEXT:    call void @f1()206; CHECK-NEXT:    br label [[IF2:%.*]]207; CHECK:       if.else:208; CHECK-NEXT:    call void @f2()209; CHECK-NEXT:    br label [[IF2]]210; CHECK:       if2:211; CHECK-NEXT:    br i1 false, label [[IF_THEN2:%.*]], label [[FOR_INC]]212; CHECK:       if.then2:213; CHECK-NEXT:    call void @f1()214; CHECK-NEXT:    br label [[FOR_INC]]215; CHECK:       for.inc:216; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_05]], 1217; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K]]218; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop !{{.*}}219; CHECK:       for.end.loopexit:220; CHECK-NEXT:    br label [[FOR_END]]221; CHECK:       for.end:222; CHECK-NEXT:    ret void223;224for.body.lr.ph:225  br label %for.body226 227for.body:228  %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]229  %cmp1 = icmp ult i32 %i.05, 2230  br i1 %cmp1, label %if.then, label %if.else231 232if.then:233  call void @f1()234  br label %if2235 236if.else:237  call void @f2()238  br label %if2239 240if2:241  %cmp2 = icmp ult i32 %i.05, 4242  br i1 %cmp2, label %if.then2, label %for.inc243 244if.then2:245  call void @f1()246  br label %for.inc247 248for.inc:249  %inc = add nsw i32 %i.05, 1250  %cmp = icmp slt i32 %inc, %k251  br i1 %cmp, label %for.body, label %for.end, !llvm.loop !2252 253for.end:254  ret void255}256 257!2 = distinct !{!2}258 259; Check that we can peel off iterations that make a condition false.260define void @test3(i32 %k) {261; CHECK-LABEL: @test3(262; CHECK-NEXT:  for.body.lr.ph:263; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]264; CHECK:       for.body.peel.begin:265; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]266; CHECK:       for.body.peel:267; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp ugt i32 0, 2268; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_ELSE_PEEL:%.*]]269; CHECK:       if.else.peel:270; CHECK-NEXT:    call void @f2()271; CHECK-NEXT:    br label [[FOR_INC_PEEL:%.*]]272; CHECK:       if.then.peel:273; CHECK-NEXT:    call void @f1()274; CHECK-NEXT:    br label [[FOR_INC_PEEL]]275; CHECK:       for.inc.peel:276; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nsw i32 0, 1277; CHECK-NEXT:    [[CMP_PEEL:%.*]] = icmp slt i32 [[INC_PEEL]], [[K:%.*]]278; CHECK-NEXT:    br i1 [[CMP_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_END:%[^,]*]]279; Verify that MD_loop metadata is dropped.280; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}281; CHECK:       for.body.peel.next:282; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]283; CHECK:       for.body.peel2:284; CHECK-NEXT:    [[CMP1_PEEL3:%.*]] = icmp ugt i32 [[INC_PEEL]], 2285; CHECK-NEXT:    br i1 [[CMP1_PEEL3]], label [[IF_THEN_PEEL5:%.*]], label [[IF_ELSE_PEEL4:%.*]]286; CHECK:       if.else.peel4:287; CHECK-NEXT:    call void @f2()288; CHECK-NEXT:    br label [[FOR_INC_PEEL6:%.*]]289; CHECK:       if.then.peel5:290; CHECK-NEXT:    call void @f1()291; CHECK-NEXT:    br label [[FOR_INC_PEEL6]]292; CHECK:       for.inc.peel6:293; CHECK-NEXT:    [[INC_PEEL7:%.*]] = add nsw i32 [[INC_PEEL]], 1294; CHECK-NEXT:    [[CMP_PEEL8:%.*]] = icmp slt i32 [[INC_PEEL7]], [[K]]295; CHECK-NEXT:    br i1 [[CMP_PEEL8]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_END]]296; Verify that MD_loop metadata is dropped.297; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}298; CHECK:       for.body.peel.next1:299; CHECK-NEXT:    br label [[FOR_BODY_PEEL10:%.*]]300; CHECK:       for.body.peel10:301; CHECK-NEXT:    [[CMP1_PEEL11:%.*]] = icmp ugt i32 [[INC_PEEL7]], 2302; CHECK-NEXT:    br i1 [[CMP1_PEEL11]], label [[IF_THEN_PEEL13:%.*]], label [[IF_ELSE_PEEL12:%.*]]303; CHECK:       if.else.peel12:304; CHECK-NEXT:    call void @f2()305; CHECK-NEXT:    br label [[FOR_INC_PEEL14:%.*]]306; CHECK:       if.then.peel13:307; CHECK-NEXT:    call void @f1()308; CHECK-NEXT:    br label [[FOR_INC_PEEL14]]309; CHECK:       for.inc.peel14:310; CHECK-NEXT:    [[INC_PEEL15:%.*]] = add nsw i32 [[INC_PEEL7]], 1311; CHECK-NEXT:    [[CMP_PEEL16:%.*]] = icmp slt i32 [[INC_PEEL15]], [[K]]312; CHECK-NEXT:    br i1 [[CMP_PEEL16]], label [[FOR_BODY_PEEL_NEXT9:%.*]], label [[FOR_END]]313; Verify that MD_loop metadata is dropped.314; CHECK-NOT:   , !llvm.loop !{{[0-9]*}}315; CHECK:       for.body.peel.next9:316; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT17:%.*]]317; CHECK:       for.body.peel.next17:318; CHECK-NEXT:    br label [[FOR_BODY_LR_PH_PEEL_NEWPH:%.*]]319; CHECK:       for.body.lr.ph.peel.newph:320; CHECK-NEXT:    br label [[FOR_BODY:%.*]]321; CHECK:       for.body:322; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ [[INC_PEEL15]], [[FOR_BODY_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]323; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]324; CHECK:       if.then:325; CHECK-NEXT:    call void @f1()326; CHECK-NEXT:    br label [[FOR_INC]]327; CHECK:       if.else:328; CHECK-NEXT:    call void @f2()329; CHECK-NEXT:    br label [[FOR_INC]]330; CHECK:       for.inc:331; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_05]], 1332; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K]]333; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop !{{.*}}334; CHECK:       for.end.loopexit:335; CHECK-NEXT:    br label [[FOR_END]]336; CHECK:       for.end:337; CHECK-NEXT:    ret void338;339for.body.lr.ph:340  br label %for.body341 342for.body:343  %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]344  %cmp1 = icmp ugt i32 %i.05, 2345  br i1 %cmp1, label %if.then, label %if.else346 347if.then:348  call void @f1()349  br label %for.inc350 351if.else:352  call void @f2()353  br label %for.inc354 355for.inc:356  %inc = add nsw i32 %i.05, 1357  %cmp = icmp slt i32 %inc, %k358  br i1 %cmp, label %for.body, label %for.end, !llvm.loop !3359 360for.end:361  ret void362}363 364!3 = distinct !{!3}365 366; Test that we only peel off iterations if it simplifies a condition in the367; loop body after peeling at most MaxPeelCount iterations.368define void @test4(i32 %k) {369; CHECK-LABEL: @test4(370; CHECK-NEXT:  for.body.lr.ph:371; CHECK-NEXT:    br label [[FOR_BODY:%.*]]372; CHECK:       for.body:373; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]374; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i32 [[I_05]], 9999375; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]376; CHECK:       if.then:377; CHECK-NEXT:    call void @f1()378; CHECK-NEXT:    br label [[FOR_INC]]379; CHECK:       for.inc:380; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_05]], 1381; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]]382; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]383; CHECK:       for.end:384; CHECK-NEXT:    ret void385;386for.body.lr.ph:387  br label %for.body388 389for.body:390  %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]391  %cmp1 = icmp ugt i32 %i.05, 9999392  br i1 %cmp1, label %if.then, label %for.inc393 394if.then:395  call void @f1()396  br label %for.inc397 398for.inc:399  %inc = add nsw i32 %i.05, 1400  %cmp = icmp slt i32 %inc, %k401  br i1 %cmp, label %for.body, label %for.end402 403for.end:404  ret void405}406 407; In this test, the condition involves 2 AddRecs. Without evaluating both408; AddRecs, we cannot prove that the condition becomes known in the loop body409; after peeling.410define void @test5(i32 %k) {411; CHECK-LABEL: @test5(412; CHECK-NEXT:  entry:413; CHECK-NEXT:    br label [[FOR_BODY:%.*]]414; CHECK:       for.body:415; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]416; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 4, [[ENTRY]] ], [ [[J_INC:%.*]], [[FOR_INC]] ]417; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I_05]], [[J]]418; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]419; CHECK:       if.then:420; CHECK-NEXT:    call void @f1()421; CHECK-NEXT:    br label [[FOR_INC]]422; CHECK:       if.else:423; CHECK-NEXT:    call void @f2()424; CHECK-NEXT:    br label [[FOR_INC]]425; CHECK:       for.inc:426; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_05]], 2427; CHECK-NEXT:    [[J_INC]] = add nsw i32 [[J]], 1428; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]]429; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]430; CHECK:       for.end:431; CHECK-NEXT:    ret void432;433entry:434  br label %for.body435 436for.body:437  %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]438  %j = phi i32 [ 4, %entry ], [ %j.inc, %for.inc ]439  %cmp1 = icmp ult i32 %i.05, %j440  br i1 %cmp1, label %if.then, label %if.else441 442if.then:443  call void @f1()444  br label %for.inc445 446if.else:447  call void @f2()448  br label %for.inc449 450for.inc:451  %inc = add nsw i32 %i.05, 2452  %j.inc = add nsw i32 %j, 1453  %cmp = icmp slt i32 %inc, %k454  br i1 %cmp, label %for.body, label %for.end455 456for.end:457  ret void458}459 460define void @test6(i32 %k) {461; CHECK-LABEL: @test6(462; CHECK-NEXT:  for.body.lr.ph:463; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]464; CHECK:       for.body.peel.begin:465; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]466; CHECK:       for.body.peel:467; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp ne i32 0, 3468; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[FOR_INC_PEEL:%.*]]469; CHECK:       if.then.peel:470; CHECK-NEXT:    call void @f1()471; CHECK-NEXT:    br label [[FOR_INC_PEEL]]472; CHECK:       for.inc.peel:473; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nsw i32 0, 1474; CHECK-NEXT:    [[CMP_PEEL:%.*]] = icmp slt i32 [[INC_PEEL]], [[K:%.*]]475; CHECK-NEXT:    br i1 [[CMP_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_END:%.*]]476; CHECK:       for.body.peel.next:477; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]478; CHECK:       for.body.peel2:479; CHECK-NEXT:    [[CMP1_PEEL3:%.*]] = icmp ne i32 [[INC_PEEL]], 3480; CHECK-NEXT:    br i1 [[CMP1_PEEL3]], label [[IF_THEN_PEEL4:%.*]], label [[FOR_INC_PEEL5:%.*]]481; CHECK:       if.then.peel4:482; CHECK-NEXT:    call void @f1()483; CHECK-NEXT:    br label [[FOR_INC_PEEL5]]484; CHECK:       for.inc.peel5:485; CHECK-NEXT:    [[INC_PEEL6:%.*]] = add nsw i32 [[INC_PEEL]], 1486; CHECK-NEXT:    [[CMP_PEEL7:%.*]] = icmp slt i32 [[INC_PEEL6]], [[K]]487; CHECK-NEXT:    br i1 [[CMP_PEEL7]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_END]]488; CHECK:       for.body.peel.next1:489; CHECK-NEXT:    br label [[FOR_BODY_PEEL9:%.*]]490; CHECK:       for.body.peel9:491; CHECK-NEXT:    [[CMP1_PEEL10:%.*]] = icmp ne i32 [[INC_PEEL6]], 3492; CHECK-NEXT:    br i1 [[CMP1_PEEL10]], label [[IF_THEN_PEEL11:%.*]], label [[FOR_INC_PEEL12:%.*]]493; CHECK:       if.then.peel11:494; CHECK-NEXT:    call void @f1()495; CHECK-NEXT:    br label [[FOR_INC_PEEL12]]496; CHECK:       for.inc.peel12:497; CHECK-NEXT:    [[INC_PEEL13:%.*]] = add nsw i32 [[INC_PEEL6]], 1498; CHECK-NEXT:    [[CMP_PEEL14:%.*]] = icmp slt i32 [[INC_PEEL13]], [[K]]499; CHECK-NEXT:    br i1 [[CMP_PEEL14]], label [[FOR_BODY_PEEL_NEXT8:%.*]], label [[FOR_END]]500; CHECK:       for.body.peel.next8:501; CHECK-NEXT:    br label [[FOR_BODY_PEEL16:%.*]]502; CHECK:       for.body.peel16:503; CHECK-NEXT:    [[CMP1_PEEL17:%.*]] = icmp ne i32 [[INC_PEEL13]], 3504; CHECK-NEXT:    br i1 [[CMP1_PEEL17]], label [[IF_THEN_PEEL18:%.*]], label [[FOR_INC_PEEL19:%.*]]505; CHECK:       if.then.peel18:506; CHECK-NEXT:    call void @f1()507; CHECK-NEXT:    br label [[FOR_INC_PEEL19]]508; CHECK:       for.inc.peel19:509; CHECK-NEXT:    [[INC_PEEL20:%.*]] = add nsw i32 [[INC_PEEL13]], 1510; CHECK-NEXT:    [[CMP_PEEL21:%.*]] = icmp slt i32 [[INC_PEEL20]], [[K]]511; CHECK-NEXT:    br i1 [[CMP_PEEL21]], label [[FOR_BODY_PEEL_NEXT15:%.*]], label [[FOR_END]]512; CHECK:       for.body.peel.next15:513; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT22:%.*]]514; CHECK:       for.body.peel.next22:515; CHECK-NEXT:    br label [[FOR_BODY_LR_PH_PEEL_NEWPH:%.*]]516; CHECK:       for.body.lr.ph.peel.newph:517; CHECK-NEXT:    br label [[FOR_BODY:%.*]]518; CHECK:       for.body:519; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ [[INC_PEEL20]], [[FOR_BODY_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]520; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[FOR_INC]]521; CHECK:       if.then:522; CHECK-NEXT:    call void @f1()523; CHECK-NEXT:    br label [[FOR_INC]]524; CHECK:       for.inc:525; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_05]], 1526; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K]]527; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop !6528; CHECK:       for.end.loopexit:529; CHECK-NEXT:    br label [[FOR_END]]530; CHECK:       for.end:531; CHECK-NEXT:    ret void532;533for.body.lr.ph:534  br label %for.body535 536for.body:537  %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]538  %cmp1 = icmp ne i32 %i.05, 3539  br i1 %cmp1, label %if.then, label %for.inc540 541if.then:542  call void @f1()543  br label %for.inc544 545for.inc:546  %inc = add nsw i32 %i.05, 1547  %cmp = icmp slt i32 %inc, %k548  br i1 %cmp, label %for.body, label %for.end549 550for.end:551  ret void552}553 554define void @test7(i32 %k) {555; CHECK-LABEL: @test7(556; CHECK-NEXT:  for.body.lr.ph:557; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]558; CHECK:       for.body.peel.begin:559; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]560; CHECK:       for.body.peel:561; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp eq i32 0, 3562; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[FOR_INC_PEEL:%.*]]563; CHECK:       if.then.peel:564; CHECK-NEXT:    call void @f1()565; CHECK-NEXT:    br label [[FOR_INC_PEEL]]566; CHECK:       for.inc.peel:567; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nsw i32 0, 1568; CHECK-NEXT:    [[CMP_PEEL:%.*]] = icmp slt i32 [[INC_PEEL]], [[K:%.*]]569; CHECK-NEXT:    br i1 [[CMP_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_END:%.*]]570; CHECK:       for.body.peel.next:571; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]572; CHECK:       for.body.peel2:573; CHECK-NEXT:    [[CMP1_PEEL3:%.*]] = icmp eq i32 [[INC_PEEL]], 3574; CHECK-NEXT:    br i1 [[CMP1_PEEL3]], label [[IF_THEN_PEEL4:%.*]], label [[FOR_INC_PEEL5:%.*]]575; CHECK:       if.then.peel4:576; CHECK-NEXT:    call void @f1()577; CHECK-NEXT:    br label [[FOR_INC_PEEL5]]578; CHECK:       for.inc.peel5:579; CHECK-NEXT:    [[INC_PEEL6:%.*]] = add nsw i32 [[INC_PEEL]], 1580; CHECK-NEXT:    [[CMP_PEEL7:%.*]] = icmp slt i32 [[INC_PEEL6]], [[K]]581; CHECK-NEXT:    br i1 [[CMP_PEEL7]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_END]]582; CHECK:       for.body.peel.next1:583; CHECK-NEXT:    br label [[FOR_BODY_PEEL9:%.*]]584; CHECK:       for.body.peel9:585; CHECK-NEXT:    [[CMP1_PEEL10:%.*]] = icmp eq i32 [[INC_PEEL6]], 3586; CHECK-NEXT:    br i1 [[CMP1_PEEL10]], label [[IF_THEN_PEEL11:%.*]], label [[FOR_INC_PEEL12:%.*]]587; CHECK:       if.then.peel11:588; CHECK-NEXT:    call void @f1()589; CHECK-NEXT:    br label [[FOR_INC_PEEL12]]590; CHECK:       for.inc.peel12:591; CHECK-NEXT:    [[INC_PEEL13:%.*]] = add nsw i32 [[INC_PEEL6]], 1592; CHECK-NEXT:    [[CMP_PEEL14:%.*]] = icmp slt i32 [[INC_PEEL13]], [[K]]593; CHECK-NEXT:    br i1 [[CMP_PEEL14]], label [[FOR_BODY_PEEL_NEXT8:%.*]], label [[FOR_END]]594; CHECK:       for.body.peel.next8:595; CHECK-NEXT:    br label [[FOR_BODY_PEEL16:%.*]]596; CHECK:       for.body.peel16:597; CHECK-NEXT:    [[CMP1_PEEL17:%.*]] = icmp eq i32 [[INC_PEEL13]], 3598; CHECK-NEXT:    br i1 [[CMP1_PEEL17]], label [[IF_THEN_PEEL18:%.*]], label [[FOR_INC_PEEL19:%.*]]599; CHECK:       if.then.peel18:600; CHECK-NEXT:    call void @f1()601; CHECK-NEXT:    br label [[FOR_INC_PEEL19]]602; CHECK:       for.inc.peel19:603; CHECK-NEXT:    [[INC_PEEL20:%.*]] = add nsw i32 [[INC_PEEL13]], 1604; CHECK-NEXT:    [[CMP_PEEL21:%.*]] = icmp slt i32 [[INC_PEEL20]], [[K]]605; CHECK-NEXT:    br i1 [[CMP_PEEL21]], label [[FOR_BODY_PEEL_NEXT15:%.*]], label [[FOR_END]]606; CHECK:       for.body.peel.next15:607; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT22:%.*]]608; CHECK:       for.body.peel.next22:609; CHECK-NEXT:    br label [[FOR_BODY_LR_PH_PEEL_NEWPH:%.*]]610; CHECK:       for.body.lr.ph.peel.newph:611; CHECK-NEXT:    br label [[FOR_BODY:%.*]]612; CHECK:       for.body:613; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ [[INC_PEEL20]], [[FOR_BODY_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]614; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[FOR_INC]]615; CHECK:       if.then:616; CHECK-NEXT:    call void @f1()617; CHECK-NEXT:    br label [[FOR_INC]]618; CHECK:       for.inc:619; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_05]], 1620; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K]]621; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop !7622; CHECK:       for.end.loopexit:623; CHECK-NEXT:    br label [[FOR_END]]624; CHECK:       for.end:625; CHECK-NEXT:    ret void626;627for.body.lr.ph:628  br label %for.body629 630for.body:631  %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]632  %cmp1 = icmp eq i32 %i.05, 3633  br i1 %cmp1, label %if.then, label %for.inc634 635if.then:636  call void @f1()637  br label %for.inc638 639for.inc:640  %inc = add nsw i32 %i.05, 1641  %cmp = icmp slt i32 %inc, %k642  br i1 %cmp, label %for.body, label %for.end643 644for.end:645  ret void646}647 648define void @test8(i32 %k) {649; CHECK-LABEL: @test8(650; CHECK-NEXT:  for.body.lr.ph:651; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]652; CHECK:       for.body.peel.begin:653; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]654; CHECK:       for.body.peel:655; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp slt i32 0, 3656; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[FOR_INC_PEEL:%.*]]657; CHECK:       if.then.peel:658; CHECK-NEXT:    call void @f1()659; CHECK-NEXT:    br label [[FOR_INC_PEEL]]660; CHECK:       for.inc.peel:661; CHECK-NEXT:    [[INC_PEEL:%.*]] = add i32 0, 1662; CHECK-NEXT:    [[CMP_PEEL:%.*]] = icmp slt i32 [[INC_PEEL]], [[K:%.*]]663; CHECK-NEXT:    br i1 [[CMP_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_END:%.*]]664; CHECK:       for.body.peel.next:665; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]666; CHECK:       for.body.peel2:667; CHECK-NEXT:    [[CMP1_PEEL3:%.*]] = icmp slt i32 [[INC_PEEL]], 3668; CHECK-NEXT:    br i1 [[CMP1_PEEL3]], label [[IF_THEN_PEEL4:%.*]], label [[FOR_INC_PEEL5:%.*]]669; CHECK:       if.then.peel4:670; CHECK-NEXT:    call void @f1()671; CHECK-NEXT:    br label [[FOR_INC_PEEL5]]672; CHECK:       for.inc.peel5:673; CHECK-NEXT:    [[INC_PEEL6:%.*]] = add i32 [[INC_PEEL]], 1674; CHECK-NEXT:    [[CMP_PEEL7:%.*]] = icmp slt i32 [[INC_PEEL6]], [[K]]675; CHECK-NEXT:    br i1 [[CMP_PEEL7]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_END]]676; CHECK:       for.body.peel.next1:677; CHECK-NEXT:    br label [[FOR_BODY_PEEL9:%.*]]678; CHECK:       for.body.peel9:679; CHECK-NEXT:    [[CMP1_PEEL10:%.*]] = icmp slt i32 [[INC_PEEL6]], 3680; CHECK-NEXT:    br i1 [[CMP1_PEEL10]], label [[IF_THEN_PEEL11:%.*]], label [[FOR_INC_PEEL12:%.*]]681; CHECK:       if.then.peel11:682; CHECK-NEXT:    call void @f1()683; CHECK-NEXT:    br label [[FOR_INC_PEEL12]]684; CHECK:       for.inc.peel12:685; CHECK-NEXT:    [[INC_PEEL13:%.*]] = add i32 [[INC_PEEL6]], 1686; CHECK-NEXT:    [[CMP_PEEL14:%.*]] = icmp slt i32 [[INC_PEEL13]], [[K]]687; CHECK-NEXT:    br i1 [[CMP_PEEL14]], label [[FOR_BODY_PEEL_NEXT8:%.*]], label [[FOR_END]]688; CHECK:       for.body.peel.next8:689; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT15:%.*]]690; CHECK:       for.body.peel.next15:691; CHECK-NEXT:    br label [[FOR_BODY_LR_PH_PEEL_NEWPH:%.*]]692; CHECK:       for.body.lr.ph.peel.newph:693; CHECK-NEXT:    br label [[FOR_BODY:%.*]]694; CHECK:       for.body:695; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ [[INC_PEEL13]], [[FOR_BODY_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]696; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[FOR_INC]]697; CHECK:       if.then:698; CHECK-NEXT:    call void @f1()699; CHECK-NEXT:    br label [[FOR_INC]]700; CHECK:       for.inc:701; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_05]], 1702; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K]]703; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop [[LOOP8:![0-9]+]]704; CHECK:       for.end.loopexit:705; CHECK-NEXT:    br label [[FOR_END]]706; CHECK:       for.end:707; CHECK-NEXT:    ret void708;709for.body.lr.ph:710  br label %for.body711 712for.body:713  %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]714  %cmp1 = icmp slt i32 %i.05, 3715  br i1 %cmp1, label %if.then, label %for.inc716 717if.then:718  call void @f1()719  br label %for.inc720 721for.inc:722  %inc = add i32 %i.05, 1723  %cmp = icmp slt i32 %inc, %k724  br i1 %cmp, label %for.body, label %for.end725 726for.end:727  ret void728}729; CHECK-NOT: llvm.loop.unroll.disable730 731define void @test_9__peel_first_iter_via_slt_pred(i32 %len) {732; CHECK-LABEL: @test_9__peel_first_iter_via_slt_pred(733; CHECK-NEXT:  entry:734; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[LEN:%.*]], 0735; CHECK-NEXT:    br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]736; CHECK:       for.body.preheader:737; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]738; CHECK:       for.body.peel.begin:739; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]740; CHECK:       for.body.peel:741; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp slt i32 0, 1742; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_END_PEEL:%.*]]743; CHECK:       if.then.peel:744; CHECK-NEXT:    call void @init()745; CHECK-NEXT:    br label [[IF_END_PEEL]]746; CHECK:       if.end.peel:747; CHECK-NEXT:    call void @sink()748; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nuw nsw i32 0, 1749; CHECK-NEXT:    [[EXITCOND_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], [[LEN]]750; CHECK-NEXT:    br i1 [[EXITCOND_PEEL]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY_PEEL_NEXT:%.*]]751; CHECK:       for.body.peel.next:752; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT1:%.*]]753; CHECK:       for.body.peel.next1:754; CHECK-NEXT:    br label [[FOR_BODY_PREHEADER_PEEL_NEWPH:%.*]]755; CHECK:       for.body.preheader.peel.newph:756; CHECK-NEXT:    br label [[FOR_BODY:%.*]]757; CHECK:       for.cond.cleanup.loopexit.loopexit:758; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT]]759; CHECK:       for.cond.cleanup.loopexit:760; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]761; CHECK:       for.cond.cleanup:762; CHECK-NEXT:    ret void763; CHECK:       for.body:764; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ [[INC_PEEL]], [[FOR_BODY_PREHEADER_PEEL_NEWPH]] ]765; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END]]766; CHECK:       if.then:767; CHECK-NEXT:    call void @init()768; CHECK-NEXT:    br label [[IF_END]]769; CHECK:       if.end:770; CHECK-NEXT:    call void @sink()771; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 1772; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[LEN]]773; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]]774;775entry:776  %cmp5 = icmp sgt i32 %len, 0777  br i1 %cmp5, label %for.body, label %for.cond.cleanup778 779for.cond.cleanup:                                 ; preds = %if.end, %entry780  ret void781 782for.body:                                         ; preds = %entry, %if.end783  %i.06 = phi i32 [ %inc, %if.end ], [ 0, %entry ]784  %cmp1 = icmp slt i32 %i.06, 1785  br i1 %cmp1, label %if.then, label %if.end786 787if.then:                                          ; preds = %for.body788  call void @init()789  br label %if.end790 791if.end:                                           ; preds = %if.then, %for.body792  call void @sink()793  %inc = add nuw nsw i32 %i.06, 1794  %exitcond = icmp eq i32 %inc, %len795  br i1 %exitcond, label %for.cond.cleanup, label %for.body796}797 798define void @test_10__peel_first_iter_via_sgt_pred(i32 %len) {799; CHECK-LABEL: @test_10__peel_first_iter_via_sgt_pred(800; CHECK-NEXT:  entry:801; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[LEN:%.*]], 0802; CHECK-NEXT:    br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]803; CHECK:       for.body.preheader:804; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]805; CHECK:       for.body.peel.begin:806; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]807; CHECK:       for.body.peel:808; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp sgt i32 0, 0809; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_END_PEEL:%.*]], label [[IF_THEN_PEEL:%.*]]810; CHECK:       if.then.peel:811; CHECK-NEXT:    call void @init()812; CHECK-NEXT:    br label [[IF_END_PEEL]]813; CHECK:       if.end.peel:814; CHECK-NEXT:    call void @sink()815; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nuw nsw i32 0, 1816; CHECK-NEXT:    [[EXITCOND_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], [[LEN]]817; CHECK-NEXT:    br i1 [[EXITCOND_PEEL]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY_PEEL_NEXT:%.*]]818; CHECK:       for.body.peel.next:819; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT1:%.*]]820; CHECK:       for.body.peel.next1:821; CHECK-NEXT:    br label [[FOR_BODY_PREHEADER_PEEL_NEWPH:%.*]]822; CHECK:       for.body.preheader.peel.newph:823; CHECK-NEXT:    br label [[FOR_BODY:%.*]]824; CHECK:       for.cond.cleanup.loopexit.loopexit:825; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT]]826; CHECK:       for.cond.cleanup.loopexit:827; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]828; CHECK:       for.cond.cleanup:829; CHECK-NEXT:    ret void830; CHECK:       for.body:831; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ [[INC_PEEL]], [[FOR_BODY_PREHEADER_PEEL_NEWPH]] ]832; CHECK-NEXT:    br i1 true, label [[IF_END]], label [[IF_THEN:%.*]]833; CHECK:       if.then:834; CHECK-NEXT:    call void @init()835; CHECK-NEXT:    br label [[IF_END]]836; CHECK:       if.end:837; CHECK-NEXT:    call void @sink()838; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 1839; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[LEN]]840; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP11:![0-9]+]]841;842entry:843  %cmp5 = icmp sgt i32 %len, 0844  br i1 %cmp5, label %for.body, label %for.cond.cleanup845 846for.cond.cleanup:                                 ; preds = %if.end, %entry847  ret void848 849for.body:                                         ; preds = %entry, %if.end850  %i.06 = phi i32 [ %inc, %if.end ], [ 0, %entry ]851  %cmp1 = icmp sgt i32 %i.06, 0852  br i1 %cmp1, label %if.end, label %if.then853 854if.then:                                          ; preds = %for.body855  call void @init()856  br label %if.end857 858if.end:                                           ; preds = %if.then, %for.body859  call void @sink()860  %inc = add nuw nsw i32 %i.06, 1861  %exitcond = icmp eq i32 %inc, %len862  br i1 %exitcond, label %for.cond.cleanup, label %for.body863}864 865; NOTE: here we should only peel the first iteration,866;       i.e. all calls to sink() must stay in loop.867define void @test11__peel_first_iter_via_eq_pred(i32 %len) {868; CHECK-LABEL: @test11__peel_first_iter_via_eq_pred(869; CHECK-NEXT:  entry:870; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[LEN:%.*]], 0871; CHECK-NEXT:    br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]872; CHECK:       for.body.preheader:873; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]874; CHECK:       for.body.peel.begin:875; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]876; CHECK:       for.body.peel:877; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp eq i32 0, 0878; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_END_PEEL:%.*]]879; CHECK:       if.then.peel:880; CHECK-NEXT:    call void @init()881; CHECK-NEXT:    br label [[IF_END_PEEL]]882; CHECK:       if.end.peel:883; CHECK-NEXT:    call void @sink()884; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nuw nsw i32 0, 1885; CHECK-NEXT:    [[EXITCOND_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], [[LEN]]886; CHECK-NEXT:    br i1 [[EXITCOND_PEEL]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY_PEEL_NEXT:%.*]]887; CHECK:       for.body.peel.next:888; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT1:%.*]]889; CHECK:       for.body.peel.next1:890; CHECK-NEXT:    br label [[FOR_BODY_PREHEADER_PEEL_NEWPH:%.*]]891; CHECK:       for.body.preheader.peel.newph:892; CHECK-NEXT:    br label [[FOR_BODY:%.*]]893; CHECK:       for.cond.cleanup.loopexit.loopexit:894; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT]]895; CHECK:       for.cond.cleanup.loopexit:896; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]897; CHECK:       for.cond.cleanup:898; CHECK-NEXT:    ret void899; CHECK:       for.body:900; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ [[INC_PEEL]], [[FOR_BODY_PREHEADER_PEEL_NEWPH]] ]901; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END]]902; CHECK:       if.then:903; CHECK-NEXT:    call void @init()904; CHECK-NEXT:    br label [[IF_END]]905; CHECK:       if.end:906; CHECK-NEXT:    call void @sink()907; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 1908; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[LEN]]909; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]910;911entry:912  %cmp5 = icmp sgt i32 %len, 0913  br i1 %cmp5, label %for.body, label %for.cond.cleanup914 915for.cond.cleanup:                                 ; preds = %if.end, %entry916  ret void917 918for.body:                                         ; preds = %entry, %if.end919  %i.06 = phi i32 [ %inc, %if.end ], [ 0, %entry ]920  %cmp1 = icmp eq i32 %i.06, 0921  br i1 %cmp1, label %if.then, label %if.end922 923if.then:                                          ; preds = %for.body924  call void @init()925  br label %if.end926 927if.end:                                           ; preds = %if.then, %for.body928  call void @sink()929  %inc = add nuw nsw i32 %i.06, 1930  %exitcond = icmp eq i32 %inc, %len931  br i1 %exitcond, label %for.cond.cleanup, label %for.body932}933 934; NOTE: here we should only peel the first iteration,935;       i.e. all calls to sink() must stay in loop.936define void @test12__peel_first_iter_via_ne_pred(i32 %len) {937; CHECK-LABEL: @test12__peel_first_iter_via_ne_pred(938; CHECK-NEXT:  entry:939; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[LEN:%.*]], 0940; CHECK-NEXT:    br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]941; CHECK:       for.body.preheader:942; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]943; CHECK:       for.body.peel.begin:944; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]945; CHECK:       for.body.peel:946; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp ne i32 0, 0947; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_END_PEEL:%.*]], label [[IF_THEN_PEEL:%.*]]948; CHECK:       if.then.peel:949; CHECK-NEXT:    call void @init()950; CHECK-NEXT:    br label [[IF_END_PEEL]]951; CHECK:       if.end.peel:952; CHECK-NEXT:    call void @sink()953; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nuw nsw i32 0, 1954; CHECK-NEXT:    [[EXITCOND_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], [[LEN]]955; CHECK-NEXT:    br i1 [[EXITCOND_PEEL]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY_PEEL_NEXT:%.*]]956; CHECK:       for.body.peel.next:957; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT1:%.*]]958; CHECK:       for.body.peel.next1:959; CHECK-NEXT:    br label [[FOR_BODY_PREHEADER_PEEL_NEWPH:%.*]]960; CHECK:       for.body.preheader.peel.newph:961; CHECK-NEXT:    br label [[FOR_BODY:%.*]]962; CHECK:       for.cond.cleanup.loopexit.loopexit:963; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT]]964; CHECK:       for.cond.cleanup.loopexit:965; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]966; CHECK:       for.cond.cleanup:967; CHECK-NEXT:    ret void968; CHECK:       for.body:969; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ [[INC_PEEL]], [[FOR_BODY_PREHEADER_PEEL_NEWPH]] ]970; CHECK-NEXT:    br i1 true, label [[IF_END]], label [[IF_THEN:%.*]]971; CHECK:       if.then:972; CHECK-NEXT:    call void @init()973; CHECK-NEXT:    br label [[IF_END]]974; CHECK:       if.end:975; CHECK-NEXT:    call void @sink()976; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 1977; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[LEN]]978; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP13:![0-9]+]]979;980entry:981  %cmp5 = icmp sgt i32 %len, 0982  br i1 %cmp5, label %for.body, label %for.cond.cleanup983 984for.cond.cleanup:                                 ; preds = %if.end, %entry985  ret void986 987for.body:                                         ; preds = %entry, %if.end988  %i.06 = phi i32 [ %inc, %if.end ], [ 0, %entry ]989  %cmp1 = icmp ne i32 %i.06, 0990  br i1 %cmp1, label %if.end, label %if.then991 992if.then:                                          ; preds = %for.body993  call void @init()994  br label %if.end995 996if.end:                                           ; preds = %if.then, %for.body997  call void @sink()998  %inc = add nuw nsw i32 %i.06, 1999  %exitcond = icmp eq i32 %inc, %len1000  br i1 %exitcond, label %for.cond.cleanup, label %for.body1001}1002 1003; No peeling is profitable here.1004define void @test13__ivar_mod2_is_1(i32 %len) {1005; CHECK-LABEL: @test13__ivar_mod2_is_1(1006; CHECK-NEXT:  entry:1007; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[LEN:%.*]], 01008; CHECK-NEXT:    br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]1009; CHECK:       for.body.preheader:1010; CHECK-NEXT:    br label [[FOR_BODY:%.*]]1011; CHECK:       for.cond.cleanup.loopexit:1012; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]1013; CHECK:       for.cond.cleanup:1014; CHECK-NEXT:    ret void1015; CHECK:       for.body:1016; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]1017; CHECK-NEXT:    [[AND:%.*]] = and i32 [[I_06]], 11018; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[AND]], 11019; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_END]], label [[IF_THEN:%.*]]1020; CHECK:       if.then:1021; CHECK-NEXT:    call void @init()1022; CHECK-NEXT:    br label [[IF_END]]1023; CHECK:       if.end:1024; CHECK-NEXT:    call void @sink()1025; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 11026; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[LEN]]1027; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]]1028;1029entry:1030  %cmp5 = icmp sgt i32 %len, 01031  br i1 %cmp5, label %for.body, label %for.cond.cleanup1032 1033for.cond.cleanup:                                 ; preds = %if.end, %entry1034  ret void1035 1036for.body:                                         ; preds = %entry, %if.end1037  %i.06 = phi i32 [ %inc, %if.end ], [ 0, %entry ]1038  %and = and i32 %i.06, 11039  %cmp1 = icmp eq i32 %and, 11040  br i1 %cmp1, label %if.end, label %if.then1041 1042if.then:                                          ; preds = %for.body1043  call void @init()1044  br label %if.end1045 1046if.end:                                           ; preds = %if.then, %for.body1047  call void @sink()1048  %inc = add nuw nsw i32 %i.06, 11049  %exitcond = icmp eq i32 %inc, %len1050  br i1 %exitcond, label %for.cond.cleanup, label %for.body1051}1052 1053; No peeling is profitable here.1054define void @test14__ivar_mod2_is_0(i32 %len) {1055; CHECK-LABEL: @test14__ivar_mod2_is_0(1056; CHECK-NEXT:  entry:1057; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[LEN:%.*]], 01058; CHECK-NEXT:    br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]1059; CHECK:       for.body.preheader:1060; CHECK-NEXT:    br label [[FOR_BODY:%.*]]1061; CHECK:       for.cond.cleanup.loopexit:1062; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]1063; CHECK:       for.cond.cleanup:1064; CHECK-NEXT:    ret void1065; CHECK:       for.body:1066; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]1067; CHECK-NEXT:    [[AND:%.*]] = and i32 [[I_06]], 11068; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[AND]], 01069; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_END]], label [[IF_THEN:%.*]]1070; CHECK:       if.then:1071; CHECK-NEXT:    call void @init()1072; CHECK-NEXT:    br label [[IF_END]]1073; CHECK:       if.end:1074; CHECK-NEXT:    call void @sink()1075; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 11076; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[LEN]]1077; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]]1078;1079entry:1080  %cmp5 = icmp sgt i32 %len, 01081  br i1 %cmp5, label %for.body, label %for.cond.cleanup1082 1083for.cond.cleanup:                                 ; preds = %if.end, %entry1084  ret void1085 1086for.body:                                         ; preds = %entry, %if.end1087  %i.06 = phi i32 [ %inc, %if.end ], [ 0, %entry ]1088  %and = and i32 %i.06, 11089  %cmp1 = icmp eq i32 %and, 01090  br i1 %cmp1, label %if.end, label %if.then1091 1092if.then:                                          ; preds = %for.body1093  call void @init()1094  br label %if.end1095 1096if.end:                                           ; preds = %if.then, %for.body1097  call void @sink()1098  %inc = add nuw nsw i32 %i.06, 11099  %exitcond = icmp eq i32 %inc, %len1100  br i1 %exitcond, label %for.cond.cleanup, label %for.body1101}1102 1103; Similar to @test6, we need to peel one extra iteration, and we can't do that1104; as per the -unroll-peel-max-count=4, so this shouldn't be peeled at all.1105define void @test15(i32 %k) {1106; CHECK-LABEL: @test15(1107; CHECK-NEXT:  for.body.lr.ph:1108; CHECK-NEXT:    br label [[FOR_BODY:%.*]]1109; CHECK:       for.body:1110; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]1111; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[I_05]], 41112; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]1113; CHECK:       if.then:1114; CHECK-NEXT:    call void @f1()1115; CHECK-NEXT:    br label [[FOR_INC]]1116; CHECK:       for.inc:1117; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_05]], 11118; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]]1119; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]1120; CHECK:       for.end:1121; CHECK-NEXT:    ret void1122;1123for.body.lr.ph:1124  br label %for.body1125 1126for.body:1127  %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]1128  %cmp1 = icmp ne i32 %i.05, 41129  br i1 %cmp1, label %if.then, label %for.inc1130 1131if.then:1132  call void @f1()1133  br label %for.inc1134 1135for.inc:1136  %inc = add nsw i32 %i.05, 11137  %cmp = icmp slt i32 %inc, %k1138  br i1 %cmp, label %for.body, label %for.end1139 1140for.end:1141  ret void1142}1143 1144; Similar to @test7, we need to peel one extra iteration, and we can't do that1145; as per the -unroll-peel-max-count=4, so this shouldn't be peeled at all.1146define void @test16(i32 %k) {1147; CHECK-LABEL: @test16(1148; CHECK-NEXT:  for.body.lr.ph:1149; CHECK-NEXT:    br label [[FOR_BODY:%.*]]1150; CHECK:       for.body:1151; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]1152; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[I_05]], 41153; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]1154; CHECK:       if.then:1155; CHECK-NEXT:    call void @f1()1156; CHECK-NEXT:    br label [[FOR_INC]]1157; CHECK:       for.inc:1158; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_05]], 11159; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]]1160; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]1161; CHECK:       for.end:1162; CHECK-NEXT:    ret void1163;1164for.body.lr.ph:1165  br label %for.body1166 1167for.body:1168  %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]1169  %cmp1 = icmp eq i32 %i.05, 41170  br i1 %cmp1, label %if.then, label %for.inc1171 1172if.then:1173  call void @f1()1174  br label %for.inc1175 1176for.inc:1177  %inc = add nsw i32 %i.05, 11178  %cmp = icmp slt i32 %inc, %k1179  br i1 %cmp, label %for.body, label %for.end1180 1181for.end:1182  ret void1183}1184 1185define void @test17() personality ptr undef{1186; CHECK-LABEL: @test17(1187; CHECK-NEXT:  body:1188; CHECK-NEXT:    br label [[LOOP_PEEL_BEGIN:%.*]]1189; CHECK:       loop.peel.begin:1190; CHECK-NEXT:    br label [[LOOP_PEEL:%.*]]1191; CHECK:       loop.peel:1192; CHECK-NEXT:    invoke void @f1()1193; CHECK-NEXT:    to label [[LOOP_PEEL_NEXT:%.*]] unwind label [[EH_UNW_LOOPEXIT_LOOPEXIT_SPLIT_LP:%.*]]1194; CHECK:       loop.peel.next:1195; CHECK-NEXT:    br label [[LOOP_PEEL_NEXT1:%.*]]1196; CHECK:       loop.peel.next1:1197; CHECK-NEXT:    br label [[BODY_PEEL_NEWPH:%.*]]1198; CHECK:       body.peel.newph:1199; CHECK-NEXT:    br label [[LOOP:%.*]]1200; CHECK:       loop:1201; CHECK-NEXT:    invoke void @f1()1202; CHECK-NEXT:    to label [[LOOP]] unwind label [[EH_UNW_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP14:![0-9]+]]1203; CHECK:       eh.Unw.loopexit.loopexit:1204; CHECK-NEXT:    [[LPAD_LOOPEXIT2:%.*]] = landingpad { ptr, i32 }1205; CHECK-NEXT:    catch ptr null1206; CHECK-NEXT:    br label [[EH_UNW_LOOPEXIT:%.*]]1207; CHECK:       eh.Unw.loopexit.loopexit.split-lp:1208; CHECK-NEXT:    [[LPAD_LOOPEXIT_SPLIT_LP:%.*]] = landingpad { ptr, i32 }1209; CHECK-NEXT:    catch ptr null1210; CHECK-NEXT:    br label [[EH_UNW_LOOPEXIT]]1211; CHECK:       eh.Unw.loopexit:1212; CHECK-NEXT:    ret void1213;1214body:1215  br label %loop1216 1217loop:1218  %const = phi i64 [ -33, %loop ], [ -20, %body ]1219  invoke void @f1()1220  to label %loop unwind label %eh.Unw.loopexit1221 1222eh.Unw.loopexit:1223  %lpad.loopexit = landingpad { ptr, i32 }1224  catch ptr null1225  ret void1226}1227 1228; Testcase reduced from PR48812.1229define void @test18(ptr %p) {1230; CHECK-LABEL: @test18(1231; CHECK-NEXT:  init:1232; CHECK-NEXT:    br label [[LOOP_PEEL_BEGIN:%.*]]1233; CHECK:       loop.peel.begin:1234; CHECK-NEXT:    br label [[LOOP_PEEL:%.*]]1235; CHECK:       loop.peel:1236; CHECK-NEXT:    br label [[LATCH_PEEL:%.*]]1237; CHECK:       latch.peel:1238; CHECK-NEXT:    [[CONTROL_PEEL:%.*]] = load volatile i32, ptr [[P:%.*]], align 41239; CHECK-NEXT:    switch i32 [[CONTROL_PEEL]], label [[EXIT:%.*]] [1240; CHECK-NEXT:    i32 2, label [[LOOP_PEEL_NEXT:%.*]]1241; CHECK-NEXT:    ]1242; CHECK:       loop.peel.next:1243; CHECK-NEXT:    br label [[LOOP_PEEL_NEXT1:%.*]]1244; CHECK:       loop.peel.next1:1245; CHECK-NEXT:    br label [[INIT_PEEL_NEWPH:%.*]]1246; CHECK:       init.peel.newph:1247; CHECK-NEXT:    br label [[LOOP:%.*]]1248; CHECK:       loop:1249; CHECK-NEXT:    br label [[LATCH:%.*]]1250; CHECK:       latch:1251; CHECK-NEXT:    [[CONTROL:%.*]] = load volatile i32, ptr [[P]], align 41252; CHECK-NEXT:    switch i32 [[CONTROL]], label [[EXIT_LOOPEXIT:%.*]] [1253; CHECK-NEXT:    i32 2, label [[LOOP]]1254; CHECK-NEXT:    ], !llvm.loop [[LOOP15:![0-9]+]]1255; CHECK:       exit.loopexit:1256; CHECK-NEXT:    br label [[EXIT]]1257; CHECK:       exit:1258; CHECK-NEXT:    ret void1259;1260init:1261  br label %loop1262 1263loop:1264  %const = phi i32 [ 40, %init ], [ 0, %latch ]1265  br label %latch1266 1267latch:1268  %control = load volatile i32, ptr %p1269  switch i32 %control, label %exit [1270  i32 2, label %loop1271  ]1272 1273exit:1274  ret void1275}1276 1277; Test that we can peel based on a select's condition1278define void @test19(i32 %num, i32 %a, i32 %b) {1279; CHECK-LABEL: @test19(1280; CHECK-NEXT:  entry:1281; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[NUM:%.*]], 01282; CHECK-NEXT:    br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]1283; CHECK:       for.body.preheader:1284; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]1285; CHECK:       for.body.peel.begin:1286; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]1287; CHECK:       for.body.peel:1288; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp eq i32 0, 01289; CHECK-NEXT:    [[COND_PEEL:%.*]] = select i1 [[CMP1_PEEL]], i32 [[A:%.*]], i32 [[B:%.*]]1290; CHECK-NEXT:    tail call void @f3(i32 noundef [[COND_PEEL]])1291; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nuw nsw i32 0, 11292; CHECK-NEXT:    [[EXITCOND_NOT_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], [[NUM]]1293; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY_PEEL_NEXT:%.*]]1294; CHECK:       for.body.peel.next:1295; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT1:%.*]]1296; CHECK:       for.body.peel.next1:1297; CHECK-NEXT:    br label [[FOR_BODY_PREHEADER_PEEL_NEWPH:%.*]]1298; CHECK:       for.body.preheader.peel.newph:1299; CHECK-NEXT:    br label [[FOR_BODY:%.*]]1300; CHECK:       for.cond.cleanup.loopexit.loopexit:1301; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT]]1302; CHECK:       for.cond.cleanup.loopexit:1303; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]1304; CHECK:       for.cond.cleanup:1305; CHECK-NEXT:    ret void1306; CHECK:       for.body:1307; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY]] ], [ [[INC_PEEL]], [[FOR_BODY_PREHEADER_PEEL_NEWPH]] ]1308; CHECK-NEXT:    tail call void @f3(i32 noundef [[B]])1309; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 11310; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]]1311; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]1312;1313entry:1314  %cmp5 = icmp sgt i32 %num, 01315  br i1 %cmp5, label %for.body, label %for.cond.cleanup1316 1317for.cond.cleanup:                                 ; preds = %for.body, %entry1318  ret void1319 1320for.body:                                         ; preds = %entry, %for.body1321  %i.06 = phi i32 [ %inc, %for.body ], [ 0, %entry ]1322  %cmp1 = icmp eq i32 %i.06, 01323  %cond = select i1 %cmp1, i32 %a, i32 %b1324  tail call void @f3(i32 noundef %cond) #21325  %inc = add nuw nsw i32 %i.06, 11326  %exitcond.not = icmp eq i32 %inc, %num1327  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body1328}1329 1330; Test we can peel based on a and's LHS condition1331define void @test20(i32 %num, i32 %a, i32 %b) {1332; CHECK-LABEL: @test20(1333; CHECK-NEXT:  entry:1334; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[NUM:%.*]], 01335; CHECK-NEXT:    br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]1336; CHECK:       for.body.preheader:1337; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]1338; CHECK:       for.body.peel.begin:1339; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]1340; CHECK:       for.body.peel:1341; CHECK-NEXT:    [[REM_PEEL:%.*]] = and i32 0, 11342; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp eq i32 [[REM_PEEL]], 01343; CHECK-NEXT:    [[CMP2_PEEL:%.*]] = icmp ult i32 0, 31344; CHECK-NEXT:    [[AND_COND_PEEL:%.*]] = and i1 [[CMP2_PEEL]], [[CMP1_PEEL]]1345; CHECK-NEXT:    br i1 [[AND_COND_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_END_PEEL:%.*]]1346; CHECK:       if.then.peel:1347; CHECK-NEXT:    tail call void (...) @f1()1348; CHECK-NEXT:    br label [[IF_END_PEEL]]1349; CHECK:       if.end.peel:1350; CHECK-NEXT:    tail call void (...) @f2()1351; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nuw nsw i32 0, 11352; CHECK-NEXT:    [[EXITCOND_NOT_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], [[NUM]]1353; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY_PEEL_NEXT:%.*]]1354; CHECK:       for.body.peel.next:1355; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]1356; CHECK:       for.body.peel2:1357; CHECK-NEXT:    [[REM_PEEL3:%.*]] = and i32 [[INC_PEEL]], 11358; CHECK-NEXT:    [[CMP1_PEEL4:%.*]] = icmp eq i32 [[REM_PEEL3]], 01359; CHECK-NEXT:    [[CMP2_PEEL5:%.*]] = icmp ult i32 [[INC_PEEL]], 31360; CHECK-NEXT:    [[AND_COND_PEEL6:%.*]] = and i1 [[CMP2_PEEL5]], [[CMP1_PEEL4]]1361; CHECK-NEXT:    br i1 [[AND_COND_PEEL6]], label [[IF_THEN_PEEL7:%.*]], label [[IF_END_PEEL8:%.*]]1362; CHECK:       if.then.peel7:1363; CHECK-NEXT:    tail call void (...) @f1()1364; CHECK-NEXT:    br label [[IF_END_PEEL8]]1365; CHECK:       if.end.peel8:1366; CHECK-NEXT:    tail call void (...) @f2()1367; CHECK-NEXT:    [[INC_PEEL9:%.*]] = add nuw nsw i32 [[INC_PEEL]], 11368; CHECK-NEXT:    [[EXITCOND_NOT_PEEL10:%.*]] = icmp eq i32 [[INC_PEEL9]], [[NUM]]1369; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL10]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[FOR_BODY_PEEL_NEXT1:%.*]]1370; CHECK:       for.body.peel.next1:1371; CHECK-NEXT:    br label [[FOR_BODY_PEEL12:%.*]]1372; CHECK:       for.body.peel12:1373; CHECK-NEXT:    [[REM_PEEL13:%.*]] = and i32 [[INC_PEEL9]], 11374; CHECK-NEXT:    [[CMP1_PEEL14:%.*]] = icmp eq i32 [[REM_PEEL13]], 01375; CHECK-NEXT:    [[CMP2_PEEL15:%.*]] = icmp ult i32 [[INC_PEEL9]], 31376; CHECK-NEXT:    [[AND_COND_PEEL16:%.*]] = and i1 [[CMP2_PEEL15]], [[CMP1_PEEL14]]1377; CHECK-NEXT:    br i1 [[AND_COND_PEEL16]], label [[IF_THEN_PEEL17:%.*]], label [[IF_END_PEEL18:%.*]]1378; CHECK:       if.then.peel17:1379; CHECK-NEXT:    tail call void (...) @f1()1380; CHECK-NEXT:    br label [[IF_END_PEEL18]]1381; CHECK:       if.end.peel18:1382; CHECK-NEXT:    tail call void (...) @f2()1383; CHECK-NEXT:    [[INC_PEEL19:%.*]] = add nuw nsw i32 [[INC_PEEL9]], 11384; CHECK-NEXT:    [[EXITCOND_NOT_PEEL20:%.*]] = icmp eq i32 [[INC_PEEL19]], [[NUM]]1385; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL20]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[FOR_BODY_PEEL_NEXT11:%.*]]1386; CHECK:       for.body.peel.next11:1387; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT21:%.*]]1388; CHECK:       for.body.peel.next21:1389; CHECK-NEXT:    br label [[FOR_BODY_PREHEADER_PEEL_NEWPH:%.*]]1390; CHECK:       for.body.preheader.peel.newph:1391; CHECK-NEXT:    br label [[FOR_BODY:%.*]]1392; CHECK:       for.cond.cleanup.loopexit.loopexit:1393; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT]]1394; CHECK:       for.cond.cleanup.loopexit:1395; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]1396; CHECK:       for.cond.cleanup:1397; CHECK-NEXT:    ret void1398; CHECK:       for.body:1399; CHECK-NEXT:    [[I_08:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ [[INC_PEEL19]], [[FOR_BODY_PREHEADER_PEEL_NEWPH]] ]1400; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END]]1401; CHECK:       if.then:1402; CHECK-NEXT:    tail call void (...) @f1()1403; CHECK-NEXT:    br label [[IF_END]]1404; CHECK:       if.end:1405; CHECK-NEXT:    tail call void (...) @f2()1406; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_08]], 11407; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]]1408; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP17:![0-9]+]]1409;1410entry:1411  %cmp5 = icmp sgt i32 %num, 01412  br i1 %cmp5, label %for.body, label %for.cond.cleanup1413 1414for.cond.cleanup:                                 ; preds = %if.end, %entry1415  ret void1416 1417for.body:                                         ; preds = %entry, %if.end1418  %i.08 = phi i32 [ %inc, %if.end ], [ 0, %entry ]1419  %rem = and i32 %i.08, 11420  %cmp1 = icmp eq i32 %rem, 01421  %cmp2 = icmp ult i32 %i.08, 31422  %and.cond = and i1 %cmp2, %cmp11423  br i1 %and.cond, label %if.then, label %if.end1424 1425if.then:                                          ; preds = %for.body1426  tail call void (...) @f1()1427  br label %if.end1428 1429if.end:                                           ; preds = %if.then, %for.body1430  tail call void (...) @f2()1431  %inc = add nuw nsw i32 %i.08, 11432  %exitcond.not = icmp eq i32 %inc, %num1433  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body1434}1435 1436; Test we can peel based on a and's RHS condition1437define void @test21(i32 %num, i32 %a, i32 %b) {1438; CHECK-LABEL: @test21(1439; CHECK-NEXT:  entry:1440; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[NUM:%.*]], 01441; CHECK-NEXT:    br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]1442; CHECK:       for.body.preheader:1443; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]1444; CHECK:       for.body.peel.begin:1445; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]1446; CHECK:       for.body.peel:1447; CHECK-NEXT:    [[REM_PEEL:%.*]] = and i32 0, 11448; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp eq i32 [[REM_PEEL]], 01449; CHECK-NEXT:    [[CMP2_PEEL:%.*]] = icmp ult i32 0, 31450; CHECK-NEXT:    [[AND_COND_PEEL:%.*]] = and i1 [[CMP1_PEEL]], [[CMP2_PEEL]]1451; CHECK-NEXT:    br i1 [[AND_COND_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_END_PEEL:%.*]]1452; CHECK:       if.then.peel:1453; CHECK-NEXT:    tail call void (...) @f1()1454; CHECK-NEXT:    br label [[IF_END_PEEL]]1455; CHECK:       if.end.peel:1456; CHECK-NEXT:    tail call void (...) @f2()1457; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nuw nsw i32 0, 11458; CHECK-NEXT:    [[EXITCOND_NOT_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], [[NUM]]1459; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY_PEEL_NEXT:%.*]]1460; CHECK:       for.body.peel.next:1461; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]1462; CHECK:       for.body.peel2:1463; CHECK-NEXT:    [[REM_PEEL3:%.*]] = and i32 [[INC_PEEL]], 11464; CHECK-NEXT:    [[CMP1_PEEL4:%.*]] = icmp eq i32 [[REM_PEEL3]], 01465; CHECK-NEXT:    [[CMP2_PEEL5:%.*]] = icmp ult i32 [[INC_PEEL]], 31466; CHECK-NEXT:    [[AND_COND_PEEL6:%.*]] = and i1 [[CMP1_PEEL4]], [[CMP2_PEEL5]]1467; CHECK-NEXT:    br i1 [[AND_COND_PEEL6]], label [[IF_THEN_PEEL7:%.*]], label [[IF_END_PEEL8:%.*]]1468; CHECK:       if.then.peel7:1469; CHECK-NEXT:    tail call void (...) @f1()1470; CHECK-NEXT:    br label [[IF_END_PEEL8]]1471; CHECK:       if.end.peel8:1472; CHECK-NEXT:    tail call void (...) @f2()1473; CHECK-NEXT:    [[INC_PEEL9:%.*]] = add nuw nsw i32 [[INC_PEEL]], 11474; CHECK-NEXT:    [[EXITCOND_NOT_PEEL10:%.*]] = icmp eq i32 [[INC_PEEL9]], [[NUM]]1475; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL10]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[FOR_BODY_PEEL_NEXT1:%.*]]1476; CHECK:       for.body.peel.next1:1477; CHECK-NEXT:    br label [[FOR_BODY_PEEL12:%.*]]1478; CHECK:       for.body.peel12:1479; CHECK-NEXT:    [[REM_PEEL13:%.*]] = and i32 [[INC_PEEL9]], 11480; CHECK-NEXT:    [[CMP1_PEEL14:%.*]] = icmp eq i32 [[REM_PEEL13]], 01481; CHECK-NEXT:    [[CMP2_PEEL15:%.*]] = icmp ult i32 [[INC_PEEL9]], 31482; CHECK-NEXT:    [[AND_COND_PEEL16:%.*]] = and i1 [[CMP1_PEEL14]], [[CMP2_PEEL15]]1483; CHECK-NEXT:    br i1 [[AND_COND_PEEL16]], label [[IF_THEN_PEEL17:%.*]], label [[IF_END_PEEL18:%.*]]1484; CHECK:       if.then.peel17:1485; CHECK-NEXT:    tail call void (...) @f1()1486; CHECK-NEXT:    br label [[IF_END_PEEL18]]1487; CHECK:       if.end.peel18:1488; CHECK-NEXT:    tail call void (...) @f2()1489; CHECK-NEXT:    [[INC_PEEL19:%.*]] = add nuw nsw i32 [[INC_PEEL9]], 11490; CHECK-NEXT:    [[EXITCOND_NOT_PEEL20:%.*]] = icmp eq i32 [[INC_PEEL19]], [[NUM]]1491; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL20]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[FOR_BODY_PEEL_NEXT11:%.*]]1492; CHECK:       for.body.peel.next11:1493; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT21:%.*]]1494; CHECK:       for.body.peel.next21:1495; CHECK-NEXT:    br label [[FOR_BODY_PREHEADER_PEEL_NEWPH:%.*]]1496; CHECK:       for.body.preheader.peel.newph:1497; CHECK-NEXT:    br label [[FOR_BODY:%.*]]1498; CHECK:       for.cond.cleanup.loopexit.loopexit:1499; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT]]1500; CHECK:       for.cond.cleanup.loopexit:1501; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]1502; CHECK:       for.cond.cleanup:1503; CHECK-NEXT:    ret void1504; CHECK:       for.body:1505; CHECK-NEXT:    [[I_08:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ [[INC_PEEL19]], [[FOR_BODY_PREHEADER_PEEL_NEWPH]] ]1506; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END]]1507; CHECK:       if.then:1508; CHECK-NEXT:    tail call void (...) @f1()1509; CHECK-NEXT:    br label [[IF_END]]1510; CHECK:       if.end:1511; CHECK-NEXT:    tail call void (...) @f2()1512; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_08]], 11513; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]]1514; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]]1515;1516entry:1517  %cmp5 = icmp sgt i32 %num, 01518  br i1 %cmp5, label %for.body, label %for.cond.cleanup1519 1520for.cond.cleanup:                                 ; preds = %if.end, %entry1521  ret void1522 1523for.body:                                         ; preds = %entry, %if.end1524  %i.08 = phi i32 [ %inc, %if.end ], [ 0, %entry ]1525  %rem = and i32 %i.08, 11526  %cmp1 = icmp eq i32 %rem, 01527  %cmp2 = icmp ult i32 %i.08, 31528  %and.cond = and i1 %cmp1, %cmp21529  br i1 %and.cond, label %if.then, label %if.end1530 1531if.then:                                          ; preds = %for.body1532  tail call void (...) @f1()1533  br label %if.end1534 1535if.end:                                           ; preds = %if.then, %for.body1536  tail call void (...) @f2()1537  %inc = add nuw nsw i32 %i.08, 11538  %exitcond.not = icmp eq i32 %inc, %num1539  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body1540}1541 1542; Test that we can peel based on a or's LHS condition1543define void @test22(i32 %num, i32 %a, i32 %b) {1544; CHECK-LABEL: @test22(1545; CHECK-NEXT:  entry:1546; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[NUM:%.*]], 01547; CHECK-NEXT:    br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]1548; CHECK:       for.body.preheader:1549; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]1550; CHECK:       for.body.peel.begin:1551; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]1552; CHECK:       for.body.peel:1553; CHECK-NEXT:    [[REM_PEEL:%.*]] = and i32 0, 11554; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp eq i32 [[REM_PEEL]], 01555; CHECK-NEXT:    [[CMP2_PEEL:%.*]] = icmp ult i32 0, 31556; CHECK-NEXT:    [[OR_COND_PEEL:%.*]] = or i1 [[CMP2_PEEL]], [[CMP1_PEEL]]1557; CHECK-NEXT:    br i1 [[OR_COND_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_END_PEEL:%.*]]1558; CHECK:       if.then.peel:1559; CHECK-NEXT:    tail call void (i32, ...) @f1(i32 [[A:%.*]])1560; CHECK-NEXT:    br label [[IF_END_PEEL]]1561; CHECK:       if.end.peel:1562; CHECK-NEXT:    tail call void (...) @f2()1563; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nuw nsw i32 0, 11564; CHECK-NEXT:    [[EXITCOND_NOT_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], [[NUM]]1565; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY_PEEL_NEXT:%.*]]1566; CHECK:       for.body.peel.next:1567; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]1568; CHECK:       for.body.peel2:1569; CHECK-NEXT:    [[REM_PEEL3:%.*]] = and i32 [[INC_PEEL]], 11570; CHECK-NEXT:    [[CMP1_PEEL4:%.*]] = icmp eq i32 [[REM_PEEL3]], 01571; CHECK-NEXT:    [[CMP2_PEEL5:%.*]] = icmp ult i32 [[INC_PEEL]], 31572; CHECK-NEXT:    [[OR_COND_PEEL6:%.*]] = or i1 [[CMP2_PEEL5]], [[CMP1_PEEL4]]1573; CHECK-NEXT:    br i1 [[OR_COND_PEEL6]], label [[IF_THEN_PEEL7:%.*]], label [[IF_END_PEEL8:%.*]]1574; CHECK:       if.then.peel7:1575; CHECK-NEXT:    tail call void (i32, ...) @f1(i32 [[A]])1576; CHECK-NEXT:    br label [[IF_END_PEEL8]]1577; CHECK:       if.end.peel8:1578; CHECK-NEXT:    tail call void (...) @f2()1579; CHECK-NEXT:    [[INC_PEEL9:%.*]] = add nuw nsw i32 [[INC_PEEL]], 11580; CHECK-NEXT:    [[EXITCOND_NOT_PEEL10:%.*]] = icmp eq i32 [[INC_PEEL9]], [[NUM]]1581; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL10]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[FOR_BODY_PEEL_NEXT1:%.*]]1582; CHECK:       for.body.peel.next1:1583; CHECK-NEXT:    br label [[FOR_BODY_PEEL12:%.*]]1584; CHECK:       for.body.peel12:1585; CHECK-NEXT:    [[REM_PEEL13:%.*]] = and i32 [[INC_PEEL9]], 11586; CHECK-NEXT:    [[CMP1_PEEL14:%.*]] = icmp eq i32 [[REM_PEEL13]], 01587; CHECK-NEXT:    [[CMP2_PEEL15:%.*]] = icmp ult i32 [[INC_PEEL9]], 31588; CHECK-NEXT:    [[OR_COND_PEEL16:%.*]] = or i1 [[CMP2_PEEL15]], [[CMP1_PEEL14]]1589; CHECK-NEXT:    br i1 [[OR_COND_PEEL16]], label [[IF_THEN_PEEL17:%.*]], label [[IF_END_PEEL18:%.*]]1590; CHECK:       if.then.peel17:1591; CHECK-NEXT:    tail call void (i32, ...) @f1(i32 [[A]])1592; CHECK-NEXT:    br label [[IF_END_PEEL18]]1593; CHECK:       if.end.peel18:1594; CHECK-NEXT:    tail call void (...) @f2()1595; CHECK-NEXT:    [[INC_PEEL19:%.*]] = add nuw nsw i32 [[INC_PEEL9]], 11596; CHECK-NEXT:    [[EXITCOND_NOT_PEEL20:%.*]] = icmp eq i32 [[INC_PEEL19]], [[NUM]]1597; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL20]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[FOR_BODY_PEEL_NEXT11:%.*]]1598; CHECK:       for.body.peel.next11:1599; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT21:%.*]]1600; CHECK:       for.body.peel.next21:1601; CHECK-NEXT:    br label [[FOR_BODY_PREHEADER_PEEL_NEWPH:%.*]]1602; CHECK:       for.body.preheader.peel.newph:1603; CHECK-NEXT:    br label [[FOR_BODY:%.*]]1604; CHECK:       for.cond.cleanup.loopexit.loopexit:1605; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT]]1606; CHECK:       for.cond.cleanup.loopexit:1607; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]1608; CHECK:       for.cond.cleanup:1609; CHECK-NEXT:    ret void1610; CHECK:       for.body:1611; CHECK-NEXT:    [[I_08:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ [[INC_PEEL19]], [[FOR_BODY_PREHEADER_PEEL_NEWPH]] ]1612; CHECK-NEXT:    [[REM:%.*]] = and i32 [[I_08]], 11613; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[REM]], 01614; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_END]]1615; CHECK:       if.then:1616; CHECK-NEXT:    tail call void (i32, ...) @f1(i32 [[A]])1617; CHECK-NEXT:    br label [[IF_END]]1618; CHECK:       if.end:1619; CHECK-NEXT:    tail call void (...) @f2()1620; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_08]], 11621; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]]1622; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP19:![0-9]+]]1623;1624entry:1625  %cmp5 = icmp sgt i32 %num, 01626  br i1 %cmp5, label %for.body, label %for.cond.cleanup1627 1628for.cond.cleanup:                                 ; preds = %if.end, %entry1629  ret void1630 1631for.body:                                         ; preds = %entry, %if.end1632  %i.08 = phi i32 [ %inc, %if.end ], [ 0, %entry ]1633  %rem = and i32 %i.08, 11634  %cmp1 = icmp eq i32 %rem, 01635  %cmp2 = icmp ult i32 %i.08, 31636  %or.cond = or i1 %cmp2, %cmp11637  br i1 %or.cond, label %if.then, label %if.end1638 1639if.then:                                          ; preds = %for.body1640  tail call void (i32, ...) @f1(i32 %a)1641  br label %if.end1642 1643if.end:                                           ; preds = %for.body, %if.then1644  tail call void (...) @f2()1645  %inc = add nuw nsw i32 %i.08, 11646  %exitcond.not = icmp eq i32 %inc, %num1647  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body1648}1649 1650; Test that we can peel based on a or's RHS condition1651define void @test23(i32 %num, i32 %a, i32 %b) {1652; CHECK-LABEL: @test23(1653; CHECK-NEXT:  entry:1654; CHECK-NEXT:    [[CMP5:%.*]] = icmp sgt i32 [[NUM:%.*]], 01655; CHECK-NEXT:    br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]1656; CHECK:       for.body.preheader:1657; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]1658; CHECK:       for.body.peel.begin:1659; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]1660; CHECK:       for.body.peel:1661; CHECK-NEXT:    [[REM_PEEL:%.*]] = and i32 0, 11662; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp eq i32 [[REM_PEEL]], 01663; CHECK-NEXT:    [[CMP2_PEEL:%.*]] = icmp ult i32 0, 31664; CHECK-NEXT:    [[OR_COND_PEEL:%.*]] = or i1 [[CMP1_PEEL]], [[CMP2_PEEL]]1665; CHECK-NEXT:    br i1 [[OR_COND_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_END_PEEL:%.*]]1666; CHECK:       if.then.peel:1667; CHECK-NEXT:    tail call void (i32, ...) @f1(i32 [[A:%.*]])1668; CHECK-NEXT:    br label [[IF_END_PEEL]]1669; CHECK:       if.end.peel:1670; CHECK-NEXT:    tail call void (...) @f2()1671; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nuw nsw i32 0, 11672; CHECK-NEXT:    [[EXITCOND_NOT_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], [[NUM]]1673; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY_PEEL_NEXT:%.*]]1674; CHECK:       for.body.peel.next:1675; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]1676; CHECK:       for.body.peel2:1677; CHECK-NEXT:    [[REM_PEEL3:%.*]] = and i32 [[INC_PEEL]], 11678; CHECK-NEXT:    [[CMP1_PEEL4:%.*]] = icmp eq i32 [[REM_PEEL3]], 01679; CHECK-NEXT:    [[CMP2_PEEL5:%.*]] = icmp ult i32 [[INC_PEEL]], 31680; CHECK-NEXT:    [[OR_COND_PEEL6:%.*]] = or i1 [[CMP1_PEEL4]], [[CMP2_PEEL5]]1681; CHECK-NEXT:    br i1 [[OR_COND_PEEL6]], label [[IF_THEN_PEEL7:%.*]], label [[IF_END_PEEL8:%.*]]1682; CHECK:       if.then.peel7:1683; CHECK-NEXT:    tail call void (i32, ...) @f1(i32 [[A]])1684; CHECK-NEXT:    br label [[IF_END_PEEL8]]1685; CHECK:       if.end.peel8:1686; CHECK-NEXT:    tail call void (...) @f2()1687; CHECK-NEXT:    [[INC_PEEL9:%.*]] = add nuw nsw i32 [[INC_PEEL]], 11688; CHECK-NEXT:    [[EXITCOND_NOT_PEEL10:%.*]] = icmp eq i32 [[INC_PEEL9]], [[NUM]]1689; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL10]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[FOR_BODY_PEEL_NEXT1:%.*]]1690; CHECK:       for.body.peel.next1:1691; CHECK-NEXT:    br label [[FOR_BODY_PEEL12:%.*]]1692; CHECK:       for.body.peel12:1693; CHECK-NEXT:    [[REM_PEEL13:%.*]] = and i32 [[INC_PEEL9]], 11694; CHECK-NEXT:    [[CMP1_PEEL14:%.*]] = icmp eq i32 [[REM_PEEL13]], 01695; CHECK-NEXT:    [[CMP2_PEEL15:%.*]] = icmp ult i32 [[INC_PEEL9]], 31696; CHECK-NEXT:    [[OR_COND_PEEL16:%.*]] = or i1 [[CMP1_PEEL14]], [[CMP2_PEEL15]]1697; CHECK-NEXT:    br i1 [[OR_COND_PEEL16]], label [[IF_THEN_PEEL17:%.*]], label [[IF_END_PEEL18:%.*]]1698; CHECK:       if.then.peel17:1699; CHECK-NEXT:    tail call void (i32, ...) @f1(i32 [[A]])1700; CHECK-NEXT:    br label [[IF_END_PEEL18]]1701; CHECK:       if.end.peel18:1702; CHECK-NEXT:    tail call void (...) @f2()1703; CHECK-NEXT:    [[INC_PEEL19:%.*]] = add nuw nsw i32 [[INC_PEEL9]], 11704; CHECK-NEXT:    [[EXITCOND_NOT_PEEL20:%.*]] = icmp eq i32 [[INC_PEEL19]], [[NUM]]1705; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL20]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[FOR_BODY_PEEL_NEXT11:%.*]]1706; CHECK:       for.body.peel.next11:1707; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT21:%.*]]1708; CHECK:       for.body.peel.next21:1709; CHECK-NEXT:    br label [[FOR_BODY_PREHEADER_PEEL_NEWPH:%.*]]1710; CHECK:       for.body.preheader.peel.newph:1711; CHECK-NEXT:    br label [[FOR_BODY:%.*]]1712; CHECK:       for.cond.cleanup.loopexit.loopexit:1713; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT]]1714; CHECK:       for.cond.cleanup.loopexit:1715; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]1716; CHECK:       for.cond.cleanup:1717; CHECK-NEXT:    ret void1718; CHECK:       for.body:1719; CHECK-NEXT:    [[I_08:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ [[INC_PEEL19]], [[FOR_BODY_PREHEADER_PEEL_NEWPH]] ]1720; CHECK-NEXT:    [[REM:%.*]] = and i32 [[I_08]], 11721; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[REM]], 01722; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_END]]1723; CHECK:       if.then:1724; CHECK-NEXT:    tail call void (i32, ...) @f1(i32 [[A]])1725; CHECK-NEXT:    br label [[IF_END]]1726; CHECK:       if.end:1727; CHECK-NEXT:    tail call void (...) @f2()1728; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_08]], 11729; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]]1730; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP20:![0-9]+]]1731;1732entry:1733  %cmp5 = icmp sgt i32 %num, 01734  br i1 %cmp5, label %for.body, label %for.cond.cleanup1735 1736for.cond.cleanup:                                 ; preds = %if.end, %entry1737  ret void1738 1739for.body:                                         ; preds = %entry, %if.end1740  %i.08 = phi i32 [ %inc, %if.end ], [ 0, %entry ]1741  %rem = and i32 %i.08, 11742  %cmp1 = icmp eq i32 %rem, 01743  %cmp2 = icmp ult i32 %i.08, 31744  %or.cond = or i1 %cmp1, %cmp21745  br i1 %or.cond, label %if.then, label %if.end1746 1747if.then:                                          ; preds = %for.body1748  tail call void (i32, ...) @f1(i32 %a)1749  br label %if.end1750 1751if.end:                                           ; preds = %for.body, %if.then1752  tail call void (...) @f2()1753  %inc = add nuw nsw i32 %i.08, 11754  %exitcond.not = icmp eq i32 %inc, %num1755  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body1756}1757 1758; Test peeling when the loop is huge, >2^641759define void @test24(i128 %k) {1760; CHECK-LABEL: @test24(1761; CHECK-NEXT:  for.body.lr.ph:1762; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]1763; CHECK:       for.body.peel.begin:1764; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]1765; CHECK:       for.body.peel:1766; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp ult i128 0, 21767; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_ELSE_PEEL:%.*]]1768; CHECK:       if.else.peel:1769; CHECK-NEXT:    call void @f2()1770; CHECK-NEXT:    br label [[FOR_INC_PEEL:%.*]]1771; CHECK:       if.then.peel:1772; CHECK-NEXT:    call void @f1()1773; CHECK-NEXT:    br label [[FOR_INC_PEEL]]1774; CHECK:       for.inc.peel:1775; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nsw i128 0, 11776; CHECK-NEXT:    [[CMP_PEEL:%.*]] = icmp slt i128 [[INC_PEEL]], [[K:%.*]]1777; CHECK-NEXT:    br i1 [[CMP_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_END:%.*]]1778; CHECK:       for.body.peel.next:1779; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]1780; CHECK:       for.body.peel2:1781; CHECK-NEXT:    [[CMP1_PEEL3:%.*]] = icmp ult i128 [[INC_PEEL]], 21782; CHECK-NEXT:    br i1 [[CMP1_PEEL3]], label [[IF_THEN_PEEL5:%.*]], label [[IF_ELSE_PEEL4:%.*]]1783; CHECK:       if.else.peel4:1784; CHECK-NEXT:    call void @f2()1785; CHECK-NEXT:    br label [[FOR_INC_PEEL6:%.*]]1786; CHECK:       if.then.peel5:1787; CHECK-NEXT:    call void @f1()1788; CHECK-NEXT:    br label [[FOR_INC_PEEL6]]1789; CHECK:       for.inc.peel6:1790; CHECK-NEXT:    [[INC_PEEL7:%.*]] = add nsw i128 [[INC_PEEL]], 11791; CHECK-NEXT:    [[CMP_PEEL8:%.*]] = icmp slt i128 [[INC_PEEL7]], [[K]]1792; CHECK-NEXT:    br i1 [[CMP_PEEL8]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_END]]1793; CHECK:       for.body.peel.next1:1794; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT9:%.*]]1795; CHECK:       for.body.peel.next9:1796; CHECK-NEXT:    br label [[FOR_BODY_LR_PH_PEEL_NEWPH:%.*]]1797; CHECK:       for.body.lr.ph.peel.newph:1798; CHECK-NEXT:    br label [[FOR_BODY:%.*]]1799; CHECK:       for.body:1800; CHECK-NEXT:    [[I_05:%.*]] = phi i128 [ [[INC_PEEL7]], [[FOR_BODY_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]1801; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]1802; CHECK:       if.then:1803; CHECK-NEXT:    call void @f1()1804; CHECK-NEXT:    br label [[FOR_INC]]1805; CHECK:       if.else:1806; CHECK-NEXT:    call void @f2()1807; CHECK-NEXT:    br label [[FOR_INC]]1808; CHECK:       for.inc:1809; CHECK-NEXT:    [[INC]] = add nuw nsw i128 [[I_05]], 11810; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i128 [[INC]], [[K]]1811; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop [[LOOP21:![0-9]+]]1812; CHECK:       for.end.loopexit:1813; CHECK-NEXT:    br label [[FOR_END]]1814; CHECK:       for.end:1815; CHECK-NEXT:    ret void1816;1817for.body.lr.ph:1818  br label %for.body1819 1820for.body:1821  %i.05 = phi i128 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]1822  %cmp1 = icmp ult i128 %i.05, 21823  br i1 %cmp1, label %if.then, label %if.else1824 1825if.then:1826  call void @f1()1827  br label %for.inc1828 1829if.else:1830  call void @f2()1831  br label %for.inc1832 1833for.inc:1834  %inc = add nsw i128 %i.05, 11835  %cmp = icmp slt i128 %inc, %k1836  br i1 %cmp, label %for.body, label %for.end, !llvm.loop !11837 1838for.end:1839  ret void1840}1841 1842; Test peeling just below the recursion limit of 41843define void @test25(i32 %num, i32 %a, i32 %b) {1844; CHECK-LABEL: @test25(1845; CHECK-NEXT:  entry:1846; CHECK-NEXT:    [[CMP_ENTRY:%.*]] = icmp sgt i32 [[NUM:%.*]], 01847; CHECK-NEXT:    br i1 [[CMP_ENTRY]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]1848; CHECK:       for.body.preheader:1849; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]1850; CHECK:       for.body.peel.begin:1851; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]1852; CHECK:       for.body.peel:1853; CHECK-NEXT:    [[REM1_PEEL:%.*]] = and i32 0, 11854; CHECK-NEXT:    [[REM2_PEEL:%.*]] = srem i32 0, 31855; CHECK-NEXT:    [[REM3_PEEL:%.*]] = srem i32 0, 71856; CHECK-NEXT:    [[REM4_PEEL:%.*]] = srem i32 0, 111857; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp ult i32 0, 31858; CHECK-NEXT:    [[CMP2_PEEL:%.*]] = icmp eq i32 [[REM1_PEEL]], 01859; CHECK-NEXT:    [[CMP3_PEEL:%.*]] = icmp eq i32 [[REM2_PEEL]], 01860; CHECK-NEXT:    [[CMP4_PEEL:%.*]] = icmp eq i32 [[REM3_PEEL]], 01861; CHECK-NEXT:    [[CMP5_PEEL:%.*]] = icmp eq i32 [[REM4_PEEL]], 01862; CHECK-NEXT:    [[OR_COND1_PEEL:%.*]] = or i1 [[CMP1_PEEL]], [[CMP2_PEEL]]1863; CHECK-NEXT:    [[OR_COND2_PEEL:%.*]] = or i1 [[OR_COND1_PEEL]], [[CMP3_PEEL]]1864; CHECK-NEXT:    [[OR_COND3_PEEL:%.*]] = or i1 [[OR_COND2_PEEL]], [[CMP4_PEEL]]1865; CHECK-NEXT:    [[OR_COND4_PEEL:%.*]] = or i1 [[OR_COND3_PEEL]], [[CMP5_PEEL]]1866; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_END_PEEL:%.*]]1867; CHECK:       if.then.peel:1868; CHECK-NEXT:    tail call void (i32, ...) @f1(i32 [[A:%.*]])1869; CHECK-NEXT:    br label [[IF_END_PEEL]]1870; CHECK:       if.end.peel:1871; CHECK-NEXT:    tail call void (...) @f2()1872; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nuw nsw i32 0, 11873; CHECK-NEXT:    [[EXITCOND_NOT_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], [[NUM]]1874; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY_PEEL_NEXT:%.*]]1875; CHECK:       for.body.peel.next:1876; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]1877; CHECK:       for.body.peel2:1878; CHECK-NEXT:    [[REM1_PEEL3:%.*]] = and i32 [[INC_PEEL]], 11879; CHECK-NEXT:    [[REM2_PEEL4:%.*]] = srem i32 [[INC_PEEL]], 31880; CHECK-NEXT:    [[REM3_PEEL5:%.*]] = srem i32 [[INC_PEEL]], 71881; CHECK-NEXT:    [[REM4_PEEL6:%.*]] = srem i32 [[INC_PEEL]], 111882; CHECK-NEXT:    [[CMP1_PEEL7:%.*]] = icmp ult i32 [[INC_PEEL]], 31883; CHECK-NEXT:    [[CMP2_PEEL8:%.*]] = icmp eq i32 [[REM1_PEEL3]], 01884; CHECK-NEXT:    [[CMP3_PEEL9:%.*]] = icmp eq i32 [[REM2_PEEL4]], 01885; CHECK-NEXT:    [[CMP4_PEEL10:%.*]] = icmp eq i32 [[REM3_PEEL5]], 01886; CHECK-NEXT:    [[CMP5_PEEL11:%.*]] = icmp eq i32 [[REM4_PEEL6]], 01887; CHECK-NEXT:    [[OR_COND1_PEEL12:%.*]] = or i1 [[CMP1_PEEL7]], [[CMP2_PEEL8]]1888; CHECK-NEXT:    [[OR_COND2_PEEL13:%.*]] = or i1 [[OR_COND1_PEEL12]], [[CMP3_PEEL9]]1889; CHECK-NEXT:    [[OR_COND3_PEEL14:%.*]] = or i1 [[OR_COND2_PEEL13]], [[CMP4_PEEL10]]1890; CHECK-NEXT:    [[OR_COND4_PEEL15:%.*]] = or i1 [[OR_COND3_PEEL14]], [[CMP5_PEEL11]]1891; CHECK-NEXT:    br i1 [[CMP1_PEEL7]], label [[IF_THEN_PEEL16:%.*]], label [[IF_END_PEEL17:%.*]]1892; CHECK:       if.then.peel16:1893; CHECK-NEXT:    tail call void (i32, ...) @f1(i32 [[A]])1894; CHECK-NEXT:    br label [[IF_END_PEEL17]]1895; CHECK:       if.end.peel17:1896; CHECK-NEXT:    tail call void (...) @f2()1897; CHECK-NEXT:    [[INC_PEEL18:%.*]] = add nuw nsw i32 [[INC_PEEL]], 11898; CHECK-NEXT:    [[EXITCOND_NOT_PEEL19:%.*]] = icmp eq i32 [[INC_PEEL18]], [[NUM]]1899; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL19]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[FOR_BODY_PEEL_NEXT1:%.*]]1900; CHECK:       for.body.peel.next1:1901; CHECK-NEXT:    br label [[FOR_BODY_PEEL21:%.*]]1902; CHECK:       for.body.peel21:1903; CHECK-NEXT:    [[REM1_PEEL22:%.*]] = and i32 [[INC_PEEL18]], 11904; CHECK-NEXT:    [[REM2_PEEL23:%.*]] = srem i32 [[INC_PEEL18]], 31905; CHECK-NEXT:    [[REM3_PEEL24:%.*]] = srem i32 [[INC_PEEL18]], 71906; CHECK-NEXT:    [[REM4_PEEL25:%.*]] = srem i32 [[INC_PEEL18]], 111907; CHECK-NEXT:    [[CMP1_PEEL26:%.*]] = icmp ult i32 [[INC_PEEL18]], 31908; CHECK-NEXT:    [[CMP2_PEEL27:%.*]] = icmp eq i32 [[REM1_PEEL22]], 01909; CHECK-NEXT:    [[CMP3_PEEL28:%.*]] = icmp eq i32 [[REM2_PEEL23]], 01910; CHECK-NEXT:    [[CMP4_PEEL29:%.*]] = icmp eq i32 [[REM3_PEEL24]], 01911; CHECK-NEXT:    [[CMP5_PEEL30:%.*]] = icmp eq i32 [[REM4_PEEL25]], 01912; CHECK-NEXT:    [[OR_COND1_PEEL31:%.*]] = or i1 [[CMP1_PEEL26]], [[CMP2_PEEL27]]1913; CHECK-NEXT:    [[OR_COND2_PEEL32:%.*]] = or i1 [[OR_COND1_PEEL31]], [[CMP3_PEEL28]]1914; CHECK-NEXT:    [[OR_COND3_PEEL33:%.*]] = or i1 [[OR_COND2_PEEL32]], [[CMP4_PEEL29]]1915; CHECK-NEXT:    [[OR_COND4_PEEL34:%.*]] = or i1 [[OR_COND3_PEEL33]], [[CMP5_PEEL30]]1916; CHECK-NEXT:    br i1 [[CMP1_PEEL26]], label [[IF_THEN_PEEL35:%.*]], label [[IF_END_PEEL36:%.*]]1917; CHECK:       if.then.peel35:1918; CHECK-NEXT:    tail call void (i32, ...) @f1(i32 [[A]])1919; CHECK-NEXT:    br label [[IF_END_PEEL36]]1920; CHECK:       if.end.peel36:1921; CHECK-NEXT:    tail call void (...) @f2()1922; CHECK-NEXT:    [[INC_PEEL37:%.*]] = add nuw nsw i32 [[INC_PEEL18]], 11923; CHECK-NEXT:    [[EXITCOND_NOT_PEEL38:%.*]] = icmp eq i32 [[INC_PEEL37]], [[NUM]]1924; CHECK-NEXT:    br i1 [[EXITCOND_NOT_PEEL38]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[FOR_BODY_PEEL_NEXT20:%.*]]1925; CHECK:       for.body.peel.next20:1926; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT39:%.*]]1927; CHECK:       for.body.peel.next39:1928; CHECK-NEXT:    br label [[FOR_BODY_PREHEADER_PEEL_NEWPH:%.*]]1929; CHECK:       for.body.preheader.peel.newph:1930; CHECK-NEXT:    br label [[FOR_BODY:%.*]]1931; CHECK:       for.cond.cleanup.loopexit.loopexit:1932; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT]]1933; CHECK:       for.cond.cleanup.loopexit:1934; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]1935; CHECK:       for.cond.cleanup:1936; CHECK-NEXT:    ret void1937; CHECK:       for.body:1938; CHECK-NEXT:    [[I_08:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ [[INC_PEEL37]], [[FOR_BODY_PREHEADER_PEEL_NEWPH]] ]1939; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_END]]1940; CHECK:       if.then:1941; CHECK-NEXT:    tail call void (i32, ...) @f1(i32 [[A]])1942; CHECK-NEXT:    br label [[IF_END]]1943; CHECK:       if.end:1944; CHECK-NEXT:    tail call void (...) @f2()1945; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_08]], 11946; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]]1947; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP22:![0-9]+]]1948;1949entry:1950  %cmp_entry = icmp sgt i32 %num, 01951  br i1 %cmp_entry, label %for.body, label %for.cond.cleanup1952 1953for.cond.cleanup:                                 ; preds = %if.end, %entry1954  ret void1955 1956for.body:                                         ; preds = %entry, %if.end1957  %i.08 = phi i32 [ %inc, %if.end ], [ 0, %entry ]1958  %rem1 = and i32 %i.08, 11959  %rem2 = srem i32 %i.08, 31960  %rem3 = srem i32 %i.08, 71961  %rem4 = srem i32 %i.08, 111962  %cmp1 = icmp ult i32 %i.08, 31963  %cmp2 = icmp eq i32 %rem1, 01964  %cmp3 = icmp eq i32 %rem2, 01965  %cmp4 = icmp eq i32 %rem3, 01966  %cmp5 = icmp eq i32 %rem4, 01967  %or.cond1 = or i1 %cmp1, %cmp21968  %or.cond2 = or i1 %or.cond1, %cmp31969  %or.cond3 = or i1 %or.cond2, %cmp41970  %or.cond4 = or i1 %or.cond3, %cmp51971  br i1 %cmp1, label %if.then, label %if.end1972 1973if.then:                                          ; preds = %for.body1974  tail call void (i32, ...) @f1(i32 %a)1975  br label %if.end1976 1977if.end:                                           ; preds = %for.body, %if.then1978  tail call void (...) @f2()1979  %inc = add nuw nsw i32 %i.08, 11980  %exitcond.not = icmp eq i32 %inc, %num1981  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body1982}1983 1984; Test peeling past the recursion limit of 41985define void @test26(i32 %num, i32 %a, i32 %b) {1986; CHECK-LABEL: @test26(1987; CHECK-NEXT:  entry:1988; CHECK-NEXT:    [[CMP_ENTRY:%.*]] = icmp sgt i32 [[NUM:%.*]], 01989; CHECK-NEXT:    br i1 [[CMP_ENTRY]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]1990; CHECK:       for.body.preheader:1991; CHECK-NEXT:    br label [[FOR_BODY:%.*]]1992; CHECK:       for.cond.cleanup.loopexit:1993; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]1994; CHECK:       for.cond.cleanup:1995; CHECK-NEXT:    ret void1996; CHECK:       for.body:1997; CHECK-NEXT:    [[I_08:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]1998; CHECK-NEXT:    [[REM1:%.*]] = and i32 [[I_08]], 11999; CHECK-NEXT:    [[REM2:%.*]] = srem i32 [[I_08]], 32000; CHECK-NEXT:    [[REM3:%.*]] = srem i32 [[I_08]], 72001; CHECK-NEXT:    [[REM4:%.*]] = srem i32 [[I_08]], 112002; CHECK-NEXT:    [[REM5:%.*]] = srem i32 [[I_08]], 132003; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I_08]], 32004; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[REM1]], 02005; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq i32 [[REM2]], 02006; CHECK-NEXT:    [[CMP4:%.*]] = icmp eq i32 [[REM3]], 02007; CHECK-NEXT:    [[CMP5:%.*]] = icmp eq i32 [[REM4]], 02008; CHECK-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[REM5]], 02009; CHECK-NEXT:    [[OR_COND1:%.*]] = or i1 [[CMP1]], [[CMP2]]2010; CHECK-NEXT:    [[OR_COND2:%.*]] = or i1 [[OR_COND1]], [[CMP3]]2011; CHECK-NEXT:    [[OR_COND3:%.*]] = or i1 [[OR_COND2]], [[CMP4]]2012; CHECK-NEXT:    [[OR_COND4:%.*]] = or i1 [[OR_COND3]], [[CMP5]]2013; CHECK-NEXT:    [[OR_COND5:%.*]] = or i1 [[OR_COND4]], [[CMP6]]2014; CHECK-NEXT:    br i1 [[OR_COND5]], label [[IF_THEN:%.*]], label [[IF_END]]2015; CHECK:       if.then:2016; CHECK-NEXT:    tail call void (i32, ...) @f1(i32 [[A:%.*]])2017; CHECK-NEXT:    br label [[IF_END]]2018; CHECK:       if.end:2019; CHECK-NEXT:    tail call void (...) @f2()2020; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_08]], 12021; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[NUM]]2022; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]]2023;2024entry:2025  %cmp_entry = icmp sgt i32 %num, 02026  br i1 %cmp_entry, label %for.body, label %for.cond.cleanup2027 2028for.cond.cleanup:                                 ; preds = %if.end, %entry2029  ret void2030 2031for.body:                                         ; preds = %entry, %if.end2032  %i.08 = phi i32 [ %inc, %if.end ], [ 0, %entry ]2033  %rem1 = and i32 %i.08, 12034  %rem2 = srem i32 %i.08, 32035  %rem3 = srem i32 %i.08, 72036  %rem4 = srem i32 %i.08, 112037  %rem5 = srem i32 %i.08, 132038  %cmp1 = icmp ult i32 %i.08, 32039  %cmp2 = icmp eq i32 %rem1, 02040  %cmp3 = icmp eq i32 %rem2, 02041  %cmp4 = icmp eq i32 %rem3, 02042  %cmp5 = icmp eq i32 %rem4, 02043  %cmp6 = icmp eq i32 %rem5, 02044  %or.cond1 = or i1 %cmp1, %cmp22045  %or.cond2 = or i1 %or.cond1, %cmp32046  %or.cond3 = or i1 %or.cond2, %cmp42047  %or.cond4 = or i1 %or.cond3, %cmp52048  %or.cond5 = or i1 %or.cond4, %cmp62049  br i1 %or.cond5, label %if.then, label %if.end2050 2051if.then:                                          ; preds = %for.body2052  tail call void (i32, ...) @f1(i32 %a)2053  br label %if.end2054 2055if.end:                                           ; preds = %for.body, %if.then2056  tail call void (...) @f2()2057  %inc = add nuw nsw i32 %i.08, 12058  %exitcond.not = icmp eq i32 %inc, %num2059  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body2060}2061 2062declare void @init()2063declare void @sink()2064