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