1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -S -loop-unroll -verify-dom-info | FileCheck %s 3 4declare void @f1() 5declare void @f2() 6 7; Check that we can peel off iterations that make conditions true. 8define void @test1(i32 %k) { 9; CHECK-LABEL: @test1( 10; CHECK-NEXT: for.body.lr.ph: 11; CHECK-NEXT: br label [[FOR_BODY_PEEL_BEGIN:%.*]] 12; CHECK: for.body.peel.begin: 13; CHECK-NEXT: br label [[FOR_BODY_PEEL:%.*]] 14; CHECK: for.body.peel: 15; CHECK-NEXT: [[CMP1_PEEL:%.*]] = icmp ult i32 0, 2 16; CHECK-NEXT: br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_ELSE_PEEL:%.*]] 17; CHECK: if.else.peel: 18; CHECK-NEXT: call void @f2() 19; CHECK-NEXT: br label [[FOR_INC_PEEL:%.*]] 20; CHECK: if.then.peel: 21; CHECK-NEXT: call void @f1() 22; CHECK-NEXT: br label [[FOR_INC_PEEL]] 23; CHECK: for.inc.peel: 24; CHECK-NEXT: [[INC_PEEL:%.*]] = add nsw i32 0, 1 25; CHECK-NEXT: [[CMP_PEEL:%.*]] = icmp slt i32 [[INC_PEEL]], [[K:%.*]] 26; CHECK-NEXT: br i1 [[CMP_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_END:%[^,]*]] 27; Verify that MD_loop metadata is dropped. 28; CHECK-NOT: , !llvm.loop !{{[0-9]*}} 29; CHECK: for.body.peel.next: 30; CHECK-NEXT: br label [[FOR_BODY_PEEL2:%.*]] 31; CHECK: for.body.peel2: 32; CHECK-NEXT: [[CMP1_PEEL3:%.*]] = icmp ult i32 [[INC_PEEL]], 2 33; CHECK-NEXT: br i1 [[CMP1_PEEL3]], label [[IF_THEN_PEEL5:%.*]], label [[IF_ELSE_PEEL4:%.*]] 34; CHECK: if.else.peel4: 35; CHECK-NEXT: call void @f2() 36; CHECK-NEXT: br label [[FOR_INC_PEEL6:%.*]] 37; CHECK: if.then.peel5: 38; CHECK-NEXT: call void @f1() 39; CHECK-NEXT: br label [[FOR_INC_PEEL6]] 40; CHECK: for.inc.peel6: 41; CHECK-NEXT: [[INC_PEEL7:%.*]] = add nsw i32 [[INC_PEEL]], 1 42; CHECK-NEXT: [[CMP_PEEL8:%.*]] = icmp slt i32 [[INC_PEEL7]], [[K]] 43; CHECK-NEXT: br i1 [[CMP_PEEL8]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_END]] 44; Verify that MD_loop metadata is dropped. 45; CHECK-NOT: , !llvm.loop !{{[0-9]*}} 46; CHECK: for.body.peel.next1: 47; CHECK-NEXT: br label [[FOR_BODY_PEEL_NEXT9:%.*]] 48; CHECK: for.body.peel.next9: 49; CHECK-NEXT: br label [[FOR_BODY_LR_PH_PEEL_NEWPH:%.*]] 50; CHECK: for.body.lr.ph.peel.newph: 51; CHECK-NEXT: br label [[FOR_BODY:%.*]] 52; CHECK: for.body: 53; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ [[INC_PEEL7]], [[FOR_BODY_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ] 54; CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 55; CHECK: if.then: 56; CHECK-NEXT: call void @f1() 57; CHECK-NEXT: br label [[FOR_INC]] 58; CHECK: if.else: 59; CHECK-NEXT: call void @f2() 60; CHECK-NEXT: br label [[FOR_INC]] 61; CHECK: for.inc: 62; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_05]], 1 63; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], [[K]] 64; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop !{{.*}} 65; CHECK: for.end.loopexit: 66; CHECK-NEXT: br label [[FOR_END]] 67; CHECK: for.end: 68; CHECK-NEXT: ret void 69; 70for.body.lr.ph: 71 br label %for.body 72 73for.body: 74 %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ] 75 %cmp1 = icmp ult i32 %i.05, 2 76 br i1 %cmp1, label %if.then, label %if.else 77 78if.then: 79 call void @f1() 80 br label %for.inc 81 82if.else: 83 call void @f2() 84 br label %for.inc 85 86for.inc: 87 %inc = add nsw i32 %i.05, 1 88 %cmp = icmp slt i32 %inc, %k 89 br i1 %cmp, label %for.body, label %for.end, !llvm.loop !1 90 91for.end: 92 ret void 93} 94 95!1 = distinct !{!1} 96 97; Check we peel off the maximum number of iterations that make conditions true. 98define void @test2(i32 %k) { 99; CHECK-LABEL: @test2( 100; CHECK-NEXT: for.body.lr.ph: 101; CHECK-NEXT: br label [[FOR_BODY_PEEL_BEGIN:%.*]] 102; CHECK: for.body.peel.begin: 103; CHECK-NEXT: br label [[FOR_BODY_PEEL:%.*]] 104; CHECK: for.body.peel: 105; CHECK-NEXT: [[CMP1_PEEL:%.*]] = icmp ult i32 0, 2 106; CHECK-NEXT: br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_ELSE_PEEL:%.*]] 107; CHECK: if.else.peel: 108; CHECK-NEXT: call void @f2() 109; CHECK-NEXT: br label [[IF2_PEEL:%.*]] 110; CHECK: if.then.peel: 111; CHECK-NEXT: call void @f1() 112; CHECK-NEXT: br label [[IF2_PEEL]] 113; CHECK: if2.peel: 114; CHECK-NEXT: [[CMP2_PEEL:%.*]] = icmp ult i32 0, 4 115; CHECK-NEXT: br i1 [[CMP2_PEEL]], label [[IF_THEN2_PEEL:%.*]], label [[FOR_INC_PEEL:%.*]] 116; CHECK: if.then2.peel: 117; CHECK-NEXT: call void @f1() 118; CHECK-NEXT: br label [[FOR_INC_PEEL]] 119; CHECK: for.inc.peel: 120; CHECK-NEXT: [[INC_PEEL:%.*]] = add nsw i32 0, 1 121; CHECK-NEXT: [[CMP_PEEL:%.*]] = icmp slt i32 [[INC_PEEL]], [[K:%.*]] 122; CHECK-NEXT: br i1 [[CMP_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_END:%[^,]*]] 123; Verify that MD_loop metadata is dropped. 124; CHECK-NOT: , !llvm.loop !{{[0-9]*}} 125; CHECK: for.body.peel.next: 126; CHECK-NEXT: br label [[FOR_BODY_PEEL2:%.*]] 127; CHECK: for.body.peel2: 128; CHECK-NEXT: [[CMP1_PEEL3:%.*]] = icmp ult i32 [[INC_PEEL]], 2 129; CHECK-NEXT: br i1 [[CMP1_PEEL3]], label [[IF_THEN_PEEL5:%.*]], label [[IF_ELSE_PEEL4:%.*]] 130; CHECK: if.else.peel4: 131; CHECK-NEXT: call void @f2() 132; CHECK-NEXT: br label [[IF2_PEEL6:%.*]] 133; CHECK: if.then.peel5: 134; CHECK-NEXT: call void @f1() 135; CHECK-NEXT: br label [[IF2_PEEL6]] 136; CHECK: if2.peel6: 137; CHECK-NEXT: [[CMP2_PEEL7:%.*]] = icmp ult i32 [[INC_PEEL]], 4 138; CHECK-NEXT: br i1 [[CMP2_PEEL7]], label [[IF_THEN2_PEEL8:%.*]], label [[FOR_INC_PEEL9:%.*]] 139; CHECK: if.then2.peel8: 140; CHECK-NEXT: call void @f1() 141; CHECK-NEXT: br label [[FOR_INC_PEEL9]] 142; CHECK: for.inc.peel9: 143; CHECK-NEXT: [[INC_PEEL10:%.*]] = add nsw i32 [[INC_PEEL]], 1 144; CHECK-NEXT: [[CMP_PEEL11:%.*]] = icmp slt i32 [[INC_PEEL10]], [[K]] 145; CHECK-NEXT: br i1 [[CMP_PEEL11]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_END]] 146; Verify that MD_loop metadata is dropped. 147; CHECK-NOT: , !llvm.loop !{{[0-9]*}} 148; CHECK: for.body.peel.next1: 149; CHECK-NEXT: br label [[FOR_BODY_PEEL13:%.*]] 150; CHECK: for.body.peel13: 151; CHECK-NEXT: [[CMP1_PEEL14:%.*]] = icmp ult i32 [[INC_PEEL10]], 2 152; CHECK-NEXT: br i1 [[CMP1_PEEL14]], label [[IF_THEN_PEEL16:%.*]], label [[IF_ELSE_PEEL15:%.*]] 153; CHECK: if.else.peel15: 154; CHECK-NEXT: call void @f2() 155; CHECK-NEXT: br label [[IF2_PEEL17:%.*]] 156; CHECK: if.then.peel16: 157; CHECK-NEXT: call void @f1() 158; CHECK-NEXT: br label [[IF2_PEEL17]] 159; CHECK: if2.peel17: 160; CHECK-NEXT: [[CMP2_PEEL18:%.*]] = icmp ult i32 [[INC_PEEL10]], 4 161; CHECK-NEXT: br i1 [[CMP2_PEEL18]], label [[IF_THEN2_PEEL19:%.*]], label [[FOR_INC_PEEL20:%.*]] 162; CHECK: if.then2.peel19: 163; CHECK-NEXT: call void @f1() 164; CHECK-NEXT: br label [[FOR_INC_PEEL20]] 165; CHECK: for.inc.peel20: 166; CHECK-NEXT: [[INC_PEEL21:%.*]] = add nsw i32 [[INC_PEEL10]], 1 167; CHECK-NEXT: [[CMP_PEEL22:%.*]] = icmp slt i32 [[INC_PEEL21]], [[K]] 168; CHECK-NEXT: br i1 [[CMP_PEEL22]], label [[FOR_BODY_PEEL_NEXT12:%.*]], label [[FOR_END]] 169; Verify that MD_loop metadata is dropped. 170; CHECK-NOT: , !llvm.loop !{{[0-9]*}} 171; CHECK: for.body.peel.next12: 172; CHECK-NEXT: br label [[FOR_BODY_PEEL24:%.*]] 173; CHECK: for.body.peel24: 174; CHECK-NEXT: [[CMP1_PEEL25:%.*]] = icmp ult i32 [[INC_PEEL21]], 2 175; CHECK-NEXT: br i1 [[CMP1_PEEL25]], label [[IF_THEN_PEEL27:%.*]], label [[IF_ELSE_PEEL26:%.*]] 176; CHECK: if.else.peel26: 177; CHECK-NEXT: call void @f2() 178; CHECK-NEXT: br label [[IF2_PEEL28:%.*]] 179; CHECK: if.then.peel27: 180; CHECK-NEXT: call void @f1() 181; CHECK-NEXT: br label [[IF2_PEEL28]] 182; CHECK: if2.peel28: 183; CHECK-NEXT: [[CMP2_PEEL29:%.*]] = icmp ult i32 [[INC_PEEL21]], 4 184; CHECK-NEXT: br i1 [[CMP2_PEEL29]], label [[IF_THEN2_PEEL30:%.*]], label [[FOR_INC_PEEL31:%.*]] 185; CHECK: if.then2.peel30: 186; CHECK-NEXT: call void @f1() 187; CHECK-NEXT: br label [[FOR_INC_PEEL31]] 188; CHECK: for.inc.peel31: 189; CHECK-NEXT: [[INC_PEEL32:%.*]] = add nsw i32 [[INC_PEEL21]], 1 190; CHECK-NEXT: [[CMP_PEEL33:%.*]] = icmp slt i32 [[INC_PEEL32]], [[K]] 191; CHECK-NEXT: br i1 [[CMP_PEEL33]], label [[FOR_BODY_PEEL_NEXT23:%.*]], label [[FOR_END]] 192; Verify that MD_loop metadata is dropped. 193; CHECK-NOT: , !llvm.loop !{{[0-9]*}} 194; CHECK: for.body.peel.next23: 195; CHECK-NEXT: br label [[FOR_BODY_PEEL_NEXT34:%.*]] 196; CHECK: for.body.peel.next34: 197; CHECK-NEXT: br label [[FOR_BODY_LR_PH_PEEL_NEWPH:%.*]] 198; CHECK: for.body.lr.ph.peel.newph: 199; CHECK-NEXT: br label [[FOR_BODY:%.*]] 200; CHECK: for.body: 201; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ [[INC_PEEL32]], [[FOR_BODY_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ] 202; CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 203; CHECK: if.then: 204; CHECK-NEXT: call void @f1() 205; CHECK-NEXT: br label [[IF2:%.*]] 206; CHECK: if.else: 207; CHECK-NEXT: call void @f2() 208; CHECK-NEXT: br label [[IF2]] 209; CHECK: if2: 210; CHECK-NEXT: br i1 false, label [[IF_THEN2:%.*]], label [[FOR_INC]] 211; CHECK: if.then2: 212; CHECK-NEXT: call void @f1() 213; CHECK-NEXT: br label [[FOR_INC]] 214; CHECK: for.inc: 215; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_05]], 1 216; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], [[K]] 217; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop !{{.*}} 218; CHECK: for.end.loopexit: 219; CHECK-NEXT: br label [[FOR_END]] 220; CHECK: for.end: 221; CHECK-NEXT: ret void 222; 223for.body.lr.ph: 224 br label %for.body 225 226for.body: 227 %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ] 228 %cmp1 = icmp ult i32 %i.05, 2 229 br i1 %cmp1, label %if.then, label %if.else 230 231if.then: 232 call void @f1() 233 br label %if2 234 235if.else: 236 call void @f2() 237 br label %if2 238 239if2: 240 %cmp2 = icmp ult i32 %i.05, 4 241 br i1 %cmp2, label %if.then2, label %for.inc 242 243if.then2: 244 call void @f1() 245 br label %for.inc 246 247for.inc: 248 %inc = add nsw i32 %i.05, 1 249 %cmp = icmp slt i32 %inc, %k 250 br i1 %cmp, label %for.body, label %for.end, !llvm.loop !2 251 252for.end: 253 ret void 254} 255 256!2 = distinct !{!2} 257 258; Check that we can peel off iterations that make a condition false. 259define void @test3(i32 %k) { 260; CHECK-LABEL: @test3( 261; CHECK-NEXT: for.body.lr.ph: 262; CHECK-NEXT: br label [[FOR_BODY_PEEL_BEGIN:%.*]] 263; CHECK: for.body.peel.begin: 264; CHECK-NEXT: br label [[FOR_BODY_PEEL:%.*]] 265; CHECK: for.body.peel: 266; CHECK-NEXT: [[CMP1_PEEL:%.*]] = icmp ugt i32 0, 2 267; CHECK-NEXT: br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_ELSE_PEEL:%.*]] 268; CHECK: if.else.peel: 269; CHECK-NEXT: call void @f2() 270; CHECK-NEXT: br label [[FOR_INC_PEEL:%.*]] 271; CHECK: if.then.peel: 272; CHECK-NEXT: call void @f1() 273; CHECK-NEXT: br label [[FOR_INC_PEEL]] 274; CHECK: for.inc.peel: 275; CHECK-NEXT: [[INC_PEEL:%.*]] = add nsw i32 0, 1 276; CHECK-NEXT: [[CMP_PEEL:%.*]] = icmp slt i32 [[INC_PEEL]], [[K:%.*]] 277; CHECK-NEXT: br i1 [[CMP_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_END:%[^,]*]] 278; Verify that MD_loop metadata is dropped. 279; CHECK-NOT: , !llvm.loop !{{[0-9]*}} 280; CHECK: for.body.peel.next: 281; CHECK-NEXT: br label [[FOR_BODY_PEEL2:%.*]] 282; CHECK: for.body.peel2: 283; CHECK-NEXT: [[CMP1_PEEL3:%.*]] = icmp ugt i32 [[INC_PEEL]], 2 284; CHECK-NEXT: br i1 [[CMP1_PEEL3]], label [[IF_THEN_PEEL5:%.*]], label [[IF_ELSE_PEEL4:%.*]] 285; CHECK: if.else.peel4: 286; CHECK-NEXT: call void @f2() 287; CHECK-NEXT: br label [[FOR_INC_PEEL6:%.*]] 288; CHECK: if.then.peel5: 289; CHECK-NEXT: call void @f1() 290; CHECK-NEXT: br label [[FOR_INC_PEEL6]] 291; CHECK: for.inc.peel6: 292; CHECK-NEXT: [[INC_PEEL7:%.*]] = add nsw i32 [[INC_PEEL]], 1 293; CHECK-NEXT: [[CMP_PEEL8:%.*]] = icmp slt i32 [[INC_PEEL7]], [[K]] 294; CHECK-NEXT: br i1 [[CMP_PEEL8]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_END]] 295; Verify that MD_loop metadata is dropped. 296; CHECK-NOT: , !llvm.loop !{{[0-9]*}} 297; CHECK: for.body.peel.next1: 298; CHECK-NEXT: br label [[FOR_BODY_PEEL10:%.*]] 299; CHECK: for.body.peel10: 300; CHECK-NEXT: [[CMP1_PEEL11:%.*]] = icmp ugt i32 [[INC_PEEL7]], 2 301; CHECK-NEXT: br i1 [[CMP1_PEEL11]], label [[IF_THEN_PEEL13:%.*]], label [[IF_ELSE_PEEL12:%.*]] 302; CHECK: if.else.peel12: 303; CHECK-NEXT: call void @f2() 304; CHECK-NEXT: br label [[FOR_INC_PEEL14:%.*]] 305; CHECK: if.then.peel13: 306; CHECK-NEXT: call void @f1() 307; CHECK-NEXT: br label [[FOR_INC_PEEL14]] 308; CHECK: for.inc.peel14: 309; CHECK-NEXT: [[INC_PEEL15:%.*]] = add nsw i32 [[INC_PEEL7]], 1 310; CHECK-NEXT: [[CMP_PEEL16:%.*]] = icmp slt i32 [[INC_PEEL15]], [[K]] 311; CHECK-NEXT: br i1 [[CMP_PEEL16]], label [[FOR_BODY_PEEL_NEXT9:%.*]], label [[FOR_END]] 312; Verify that MD_loop metadata is dropped. 313; CHECK-NOT: , !llvm.loop !{{[0-9]*}} 314; CHECK: for.body.peel.next9: 315; CHECK-NEXT: br label [[FOR_BODY_PEEL_NEXT17:%.*]] 316; CHECK: for.body.peel.next17: 317; CHECK-NEXT: br label [[FOR_BODY_LR_PH_PEEL_NEWPH:%.*]] 318; CHECK: for.body.lr.ph.peel.newph: 319; CHECK-NEXT: br label [[FOR_BODY:%.*]] 320; CHECK: for.body: 321; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ [[INC_PEEL15]], [[FOR_BODY_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ] 322; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 323; CHECK: if.then: 324; CHECK-NEXT: call void @f1() 325; CHECK-NEXT: br label [[FOR_INC]] 326; CHECK: if.else: 327; CHECK-NEXT: call void @f2() 328; CHECK-NEXT: br label [[FOR_INC]] 329; CHECK: for.inc: 330; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_05]], 1 331; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], [[K]] 332; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop !{{.*}} 333; CHECK: for.end.loopexit: 334; CHECK-NEXT: br label [[FOR_END]] 335; CHECK: for.end: 336; CHECK-NEXT: ret void 337; 338for.body.lr.ph: 339 br label %for.body 340 341for.body: 342 %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ] 343 %cmp1 = icmp ugt i32 %i.05, 2 344 br i1 %cmp1, label %if.then, label %if.else 345 346if.then: 347 call void @f1() 348 br label %for.inc 349 350if.else: 351 call void @f2() 352 br label %for.inc 353 354for.inc: 355 %inc = add nsw i32 %i.05, 1 356 %cmp = icmp slt i32 %inc, %k 357 br i1 %cmp, label %for.body, label %for.end, !llvm.loop !3 358 359for.end: 360 ret void 361} 362 363!3 = distinct !{!3} 364 365; Test that we only peel off iterations if it simplifies a condition in the 366; loop body after peeling at most MaxPeelCount iterations. 367define void @test4(i32 %k) { 368; CHECK-LABEL: @test4( 369; CHECK-NEXT: for.body.lr.ph: 370; CHECK-NEXT: br label [[FOR_BODY:%.*]] 371; CHECK: for.body: 372; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ] 373; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[I_05]], 9999 374; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]] 375; CHECK: if.then: 376; CHECK-NEXT: call void @f1() 377; CHECK-NEXT: br label [[FOR_INC]] 378; CHECK: for.inc: 379; CHECK-NEXT: [[INC]] = add nsw i32 [[I_05]], 1 380; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]] 381; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 382; CHECK: for.end: 383; CHECK-NEXT: ret void 384; 385for.body.lr.ph: 386 br label %for.body 387 388for.body: 389 %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ] 390 %cmp1 = icmp ugt i32 %i.05, 9999 391 br i1 %cmp1, label %if.then, label %for.inc 392 393if.then: 394 call void @f1() 395 br label %for.inc 396 397for.inc: 398 %inc = add nsw i32 %i.05, 1 399 %cmp = icmp slt i32 %inc, %k 400 br i1 %cmp, label %for.body, label %for.end 401 402for.end: 403 ret void 404} 405 406; In this case we cannot peel the inner loop, because the condition involves 407; the outer induction variable. 408define void @test5(i32 %k) { 409; CHECK-LABEL: @test5( 410; CHECK-NEXT: for.body.lr.ph: 411; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] 412; CHECK: outer.header: 413; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH:%.*]] ], [ [[J_INC:%.*]], [[OUTER_INC:%.*]] ] 414; CHECK-NEXT: br label [[FOR_BODY:%.*]] 415; CHECK: for.body: 416; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ 0, [[OUTER_HEADER]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ] 417; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[J]], 2 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]], 1 427; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]] 428; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[OUTER_INC]] 429; CHECK: outer.inc: 430; CHECK-NEXT: [[J_INC]] = add nsw i32 [[J]], 1 431; CHECK-NEXT: [[OUTER_CMP:%.*]] = icmp slt i32 [[J_INC]], [[K]] 432; CHECK-NEXT: br i1 [[OUTER_CMP]], label [[OUTER_HEADER]], label [[FOR_END:%.*]] 433; CHECK: for.end: 434; CHECK-NEXT: ret void 435; 436for.body.lr.ph: 437 br label %outer.header 438 439outer.header: 440 %j = phi i32 [ 0, %for.body.lr.ph ], [ %j.inc, %outer.inc ] 441 br label %for.body 442 443for.body: 444 %i.05 = phi i32 [ 0, %outer.header ], [ %inc, %for.inc ] 445 %cmp1 = icmp ult i32 %j, 2 446 br i1 %cmp1, label %if.then, label %if.else 447 448if.then: 449 call void @f1() 450 br label %for.inc 451 452if.else: 453 call void @f2() 454 br label %for.inc 455 456for.inc: 457 %inc = add nsw i32 %i.05, 1 458 %cmp = icmp slt i32 %inc, %k 459 br i1 %cmp, label %for.body, label %outer.inc 460 461outer.inc: 462 %j.inc = add nsw i32 %j, 1 463 %outer.cmp = icmp slt i32 %j.inc, %k 464 br i1 %outer.cmp, label %outer.header, label %for.end 465 466 467for.end: 468 ret void 469} 470 471; In this test, the condition involves 2 AddRecs. Without evaluating both 472; AddRecs, we cannot prove that the condition becomes known in the loop body 473; after peeling. 474define void @test6(i32 %k) { 475; CHECK-LABEL: @test6( 476; CHECK-NEXT: entry: 477; CHECK-NEXT: br label [[FOR_BODY:%.*]] 478; CHECK: for.body: 479; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ] 480; CHECK-NEXT: [[J:%.*]] = phi i32 [ 4, [[ENTRY]] ], [ [[J_INC:%.*]], [[FOR_INC]] ] 481; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[I_05]], [[J]] 482; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 483; CHECK: if.then: 484; CHECK-NEXT: call void @f1() 485; CHECK-NEXT: br label [[FOR_INC]] 486; CHECK: if.else: 487; CHECK-NEXT: call void @f2() 488; CHECK-NEXT: br label [[FOR_INC]] 489; CHECK: for.inc: 490; CHECK-NEXT: [[INC]] = add nsw i32 [[I_05]], 2 491; CHECK-NEXT: [[J_INC]] = add nsw i32 [[J]], 1 492; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]] 493; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 494; CHECK: for.end: 495; CHECK-NEXT: ret void 496; 497entry: 498 br label %for.body 499 500for.body: 501 %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] 502 %j = phi i32 [ 4, %entry ], [ %j.inc, %for.inc ] 503 %cmp1 = icmp ult i32 %i.05, %j 504 br i1 %cmp1, label %if.then, label %if.else 505 506if.then: 507 call void @f1() 508 br label %for.inc 509 510if.else: 511 call void @f2() 512 br label %for.inc 513 514for.inc: 515 %inc = add nsw i32 %i.05, 2 516 %j.inc = add nsw i32 %j, 1 517 %cmp = icmp slt i32 %inc, %k 518 br i1 %cmp, label %for.body, label %for.end 519 520for.end: 521 ret void 522} 523 524define void @test7(i32 %k) { 525; FIXME: Could simplify loop body by peeling one additional iteration after 526; i != 3 becomes false 527; CHECK-LABEL: @test7( 528; CHECK-NEXT: for.body.lr.ph: 529; CHECK-NEXT: br label [[FOR_BODY:%.*]] 530; CHECK: for.body: 531; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ] 532; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[I_05]], 3 533; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]] 534; CHECK: if.then: 535; CHECK-NEXT: call void @f1() 536; CHECK-NEXT: br label [[FOR_INC]] 537; CHECK: for.inc: 538; CHECK-NEXT: [[INC]] = add nsw i32 [[I_05]], 1 539; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]] 540; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 541; CHECK: for.end: 542; CHECK-NEXT: ret void 543; 544for.body.lr.ph: 545 br label %for.body 546 547for.body: 548 %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ] 549 %cmp1 = icmp ne i32 %i.05, 3 550 br i1 %cmp1, label %if.then, label %for.inc 551 552if.then: 553 call void @f1() 554 br label %for.inc 555 556for.inc: 557 %inc = add nsw i32 %i.05, 1 558 %cmp = icmp slt i32 %inc, %k 559 br i1 %cmp, label %for.body, label %for.end 560 561for.end: 562 ret void 563} 564 565define void @test8(i32 %k) { 566; FIXME: Could simplify loop body by peeling one additional iteration after 567; i == 3 becomes true. 568; CHECK-LABEL: @test8( 569; CHECK-NEXT: for.body.lr.ph: 570; CHECK-NEXT: br label [[FOR_BODY:%.*]] 571; CHECK: for.body: 572; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ] 573; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[I_05]], 3 574; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]] 575; CHECK: if.then: 576; CHECK-NEXT: call void @f1() 577; CHECK-NEXT: br label [[FOR_INC]] 578; CHECK: for.inc: 579; CHECK-NEXT: [[INC]] = add nsw i32 [[I_05]], 1 580; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]] 581; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 582; CHECK: for.end: 583; CHECK-NEXT: ret void 584; 585for.body.lr.ph: 586 br label %for.body 587 588for.body: 589 %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ] 590 %cmp1 = icmp eq i32 %i.05, 3 591 br i1 %cmp1, label %if.then, label %for.inc 592 593if.then: 594 call void @f1() 595 br label %for.inc 596 597for.inc: 598 %inc = add nsw i32 %i.05, 1 599 %cmp = icmp slt i32 %inc, %k 600 br i1 %cmp, label %for.body, label %for.end 601 602for.end: 603 ret void 604} 605 606; Comparison with non-monotonic predicate due to possible wrapping, loop 607; body cannot be simplified. 608define void @test9(i32 %k) { 609; CHECK-LABEL: @test9( 610; CHECK-NEXT: for.body.lr.ph: 611; CHECK-NEXT: br label [[FOR_BODY:%.*]] 612; CHECK: for.body: 613; CHECK-NEXT: [[I_05:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ] 614; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[I_05]], 3 615; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]] 616; CHECK: if.then: 617; CHECK-NEXT: call void @f1() 618; CHECK-NEXT: br label [[FOR_INC]] 619; CHECK: for.inc: 620; CHECK-NEXT: [[INC]] = add i32 [[I_05]], 1 621; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]] 622; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] 623; CHECK: for.end: 624; CHECK-NEXT: ret void 625; 626for.body.lr.ph: 627 br label %for.body 628 629for.body: 630 %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ] 631 %cmp1 = icmp slt i32 %i.05, 3 632 br i1 %cmp1, label %if.then, label %for.inc 633 634if.then: 635 call void @f1() 636 br label %for.inc 637 638for.inc: 639 %inc = add i32 %i.05, 1 640 %cmp = icmp slt i32 %inc, %k 641 br i1 %cmp, label %for.body, label %for.end 642 643for.end: 644 ret void 645} 646; CHECK-NOT: llvm.loop.unroll.disable 647 648define void @test_10__peel_first_iter_via_slt_pred(i32 %len) { 649; CHECK-LABEL: @test_10__peel_first_iter_via_slt_pred( 650; CHECK-NEXT: entry: 651; CHECK-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[LEN:%.*]], 0 652; CHECK-NEXT: br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 653; CHECK: for.body.preheader: 654; CHECK-NEXT: br label [[FOR_BODY_PEEL_BEGIN:%.*]] 655; CHECK: for.body.peel.begin: 656; CHECK-NEXT: br label [[FOR_BODY_PEEL:%.*]] 657; CHECK: for.body.peel: 658; CHECK-NEXT: [[CMP1_PEEL:%.*]] = icmp slt i32 0, 1 659; CHECK-NEXT: br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_END_PEEL:%.*]] 660; CHECK: if.then.peel: 661; CHECK-NEXT: call void @init() 662; CHECK-NEXT: br label [[IF_END_PEEL]] 663; CHECK: if.end.peel: 664; CHECK-NEXT: call void @sink() 665; CHECK-NEXT: [[INC_PEEL:%.*]] = add nuw nsw i32 0, 1 666; CHECK-NEXT: [[EXITCOND_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], [[LEN]] 667; CHECK-NEXT: br i1 [[EXITCOND_PEEL]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY_PEEL_NEXT:%.*]] 668; CHECK: for.body.peel.next: 669; CHECK-NEXT: br label [[FOR_BODY_PEEL_NEXT1:%.*]] 670; CHECK: for.body.peel.next1: 671; CHECK-NEXT: br label [[FOR_BODY_PREHEADER_PEEL_NEWPH:%.*]] 672; CHECK: for.body.preheader.peel.newph: 673; CHECK-NEXT: br label [[FOR_BODY:%.*]] 674; CHECK: for.cond.cleanup.loopexit.loopexit: 675; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT]] 676; CHECK: for.cond.cleanup.loopexit: 677; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 678; CHECK: for.cond.cleanup: 679; CHECK-NEXT: ret void 680; CHECK: for.body: 681; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ [[INC_PEEL]], [[FOR_BODY_PREHEADER_PEEL_NEWPH]] ] 682; CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_END]] 683; CHECK: if.then: 684; CHECK-NEXT: call void @init() 685; CHECK-NEXT: br label [[IF_END]] 686; CHECK: if.end: 687; CHECK-NEXT: call void @sink() 688; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 689; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[LEN]] 690; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY]], !llvm.loop !6 691; 692entry: 693 %cmp5 = icmp sgt i32 %len, 0 694 br i1 %cmp5, label %for.body, label %for.cond.cleanup 695 696for.cond.cleanup: ; preds = %if.end, %entry 697 ret void 698 699for.body: ; preds = %entry, %if.end 700 %i.06 = phi i32 [ %inc, %if.end ], [ 0, %entry ] 701 %cmp1 = icmp slt i32 %i.06, 1 702 br i1 %cmp1, label %if.then, label %if.end 703 704if.then: ; preds = %for.body 705 call void @init() 706 br label %if.end 707 708if.end: ; preds = %if.then, %for.body 709 call void @sink() 710 %inc = add nuw nsw i32 %i.06, 1 711 %exitcond = icmp eq i32 %inc, %len 712 br i1 %exitcond, label %for.cond.cleanup, label %for.body 713} 714 715define void @test_11__peel_first_iter_via_sgt_pred(i32 %len) { 716; CHECK-LABEL: @test_11__peel_first_iter_via_sgt_pred( 717; CHECK-NEXT: entry: 718; CHECK-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[LEN:%.*]], 0 719; CHECK-NEXT: br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 720; CHECK: for.body.preheader: 721; CHECK-NEXT: br label [[FOR_BODY_PEEL_BEGIN:%.*]] 722; CHECK: for.body.peel.begin: 723; CHECK-NEXT: br label [[FOR_BODY_PEEL:%.*]] 724; CHECK: for.body.peel: 725; CHECK-NEXT: [[CMP1_PEEL:%.*]] = icmp sgt i32 0, 0 726; CHECK-NEXT: br i1 [[CMP1_PEEL]], label [[IF_END_PEEL:%.*]], label [[IF_THEN_PEEL:%.*]] 727; CHECK: if.then.peel: 728; CHECK-NEXT: call void @init() 729; CHECK-NEXT: br label [[IF_END_PEEL]] 730; CHECK: if.end.peel: 731; CHECK-NEXT: call void @sink() 732; CHECK-NEXT: [[INC_PEEL:%.*]] = add nuw nsw i32 0, 1 733; CHECK-NEXT: [[EXITCOND_PEEL:%.*]] = icmp eq i32 [[INC_PEEL]], [[LEN]] 734; CHECK-NEXT: br i1 [[EXITCOND_PEEL]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY_PEEL_NEXT:%.*]] 735; CHECK: for.body.peel.next: 736; CHECK-NEXT: br label [[FOR_BODY_PEEL_NEXT1:%.*]] 737; CHECK: for.body.peel.next1: 738; CHECK-NEXT: br label [[FOR_BODY_PREHEADER_PEEL_NEWPH:%.*]] 739; CHECK: for.body.preheader.peel.newph: 740; CHECK-NEXT: br label [[FOR_BODY:%.*]] 741; CHECK: for.cond.cleanup.loopexit.loopexit: 742; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT]] 743; CHECK: for.cond.cleanup.loopexit: 744; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 745; CHECK: for.cond.cleanup: 746; CHECK-NEXT: ret void 747; CHECK: for.body: 748; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ [[INC_PEEL]], [[FOR_BODY_PREHEADER_PEEL_NEWPH]] ] 749; CHECK-NEXT: br i1 true, label [[IF_END]], label [[IF_THEN:%.*]] 750; CHECK: if.then: 751; CHECK-NEXT: call void @init() 752; CHECK-NEXT: br label [[IF_END]] 753; CHECK: if.end: 754; CHECK-NEXT: call void @sink() 755; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 756; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[LEN]] 757; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY]], !llvm.loop !8 758; 759entry: 760 %cmp5 = icmp sgt i32 %len, 0 761 br i1 %cmp5, label %for.body, label %for.cond.cleanup 762 763for.cond.cleanup: ; preds = %if.end, %entry 764 ret void 765 766for.body: ; preds = %entry, %if.end 767 %i.06 = phi i32 [ %inc, %if.end ], [ 0, %entry ] 768 %cmp1 = icmp sgt i32 %i.06, 0 769 br i1 %cmp1, label %if.end, label %if.then 770 771if.then: ; preds = %for.body 772 call void @init() 773 br label %if.end 774 775if.end: ; preds = %if.then, %for.body 776 call void @sink() 777 %inc = add nuw nsw i32 %i.06, 1 778 %exitcond = icmp eq i32 %inc, %len 779 br i1 %exitcond, label %for.cond.cleanup, label %for.body 780} 781 782define void @test12__peel_first_iter_via_eq_pred(i32 %len) { 783; CHECK-LABEL: @test12__peel_first_iter_via_eq_pred( 784; CHECK-NEXT: entry: 785; CHECK-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[LEN:%.*]], 0 786; CHECK-NEXT: br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 787; CHECK: for.body.preheader: 788; CHECK-NEXT: br label [[FOR_BODY:%.*]] 789; CHECK: for.cond.cleanup.loopexit: 790; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 791; CHECK: for.cond.cleanup: 792; CHECK-NEXT: ret void 793; CHECK: for.body: 794; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ] 795; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[I_06]], 0 796; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_END]] 797; CHECK: if.then: 798; CHECK-NEXT: call void @init() 799; CHECK-NEXT: br label [[IF_END]] 800; CHECK: if.end: 801; CHECK-NEXT: call void @sink() 802; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 803; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[LEN]] 804; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]] 805; 806entry: 807 %cmp5 = icmp sgt i32 %len, 0 808 br i1 %cmp5, label %for.body, label %for.cond.cleanup 809 810for.cond.cleanup: ; preds = %if.end, %entry 811 ret void 812 813for.body: ; preds = %entry, %if.end 814 %i.06 = phi i32 [ %inc, %if.end ], [ 0, %entry ] 815 %cmp1 = icmp eq i32 %i.06, 0 816 br i1 %cmp1, label %if.then, label %if.end 817 818if.then: ; preds = %for.body 819 call void @init() 820 br label %if.end 821 822if.end: ; preds = %if.then, %for.body 823 call void @sink() 824 %inc = add nuw nsw i32 %i.06, 1 825 %exitcond = icmp eq i32 %inc, %len 826 br i1 %exitcond, label %for.cond.cleanup, label %for.body 827} 828 829define void @test13__peel_first_iter_via_ne_pred(i32 %len) { 830; CHECK-LABEL: @test13__peel_first_iter_via_ne_pred( 831; CHECK-NEXT: entry: 832; CHECK-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[LEN:%.*]], 0 833; CHECK-NEXT: br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 834; CHECK: for.body.preheader: 835; CHECK-NEXT: br label [[FOR_BODY:%.*]] 836; CHECK: for.cond.cleanup.loopexit: 837; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 838; CHECK: for.cond.cleanup: 839; CHECK-NEXT: ret void 840; CHECK: for.body: 841; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ] 842; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[I_06]], 0 843; CHECK-NEXT: br i1 [[CMP1]], label [[IF_END]], label [[IF_THEN:%.*]] 844; CHECK: if.then: 845; CHECK-NEXT: call void @init() 846; CHECK-NEXT: br label [[IF_END]] 847; CHECK: if.end: 848; CHECK-NEXT: call void @sink() 849; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 850; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[LEN]] 851; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]] 852; 853entry: 854 %cmp5 = icmp sgt i32 %len, 0 855 br i1 %cmp5, label %for.body, label %for.cond.cleanup 856 857for.cond.cleanup: ; preds = %if.end, %entry 858 ret void 859 860for.body: ; preds = %entry, %if.end 861 %i.06 = phi i32 [ %inc, %if.end ], [ 0, %entry ] 862 %cmp1 = icmp ne i32 %i.06, 0 863 br i1 %cmp1, label %if.end, label %if.then 864 865if.then: ; preds = %for.body 866 call void @init() 867 br label %if.end 868 869if.end: ; preds = %if.then, %for.body 870 call void @sink() 871 %inc = add nuw nsw i32 %i.06, 1 872 %exitcond = icmp eq i32 %inc, %len 873 br i1 %exitcond, label %for.cond.cleanup, label %for.body 874} 875 876define void @test15__ivar_mod2_is_1(i32 %len) { 877; CHECK-LABEL: @test15__ivar_mod2_is_1( 878; CHECK-NEXT: entry: 879; CHECK-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[LEN:%.*]], 0 880; CHECK-NEXT: br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 881; CHECK: for.body.preheader: 882; CHECK-NEXT: br label [[FOR_BODY:%.*]] 883; CHECK: for.cond.cleanup.loopexit: 884; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 885; CHECK: for.cond.cleanup: 886; CHECK-NEXT: ret void 887; CHECK: for.body: 888; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ] 889; CHECK-NEXT: [[AND:%.*]] = and i32 [[I_06]], 1 890; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND]], 1 891; CHECK-NEXT: br i1 [[CMP1]], label [[IF_END]], label [[IF_THEN:%.*]] 892; CHECK: if.then: 893; CHECK-NEXT: call void @init() 894; CHECK-NEXT: br label [[IF_END]] 895; CHECK: if.end: 896; CHECK-NEXT: call void @sink() 897; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 898; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[LEN]] 899; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]] 900; 901entry: 902 %cmp5 = icmp sgt i32 %len, 0 903 br i1 %cmp5, label %for.body, label %for.cond.cleanup 904 905for.cond.cleanup: ; preds = %if.end, %entry 906 ret void 907 908for.body: ; preds = %entry, %if.end 909 %i.06 = phi i32 [ %inc, %if.end ], [ 0, %entry ] 910 %and = and i32 %i.06, 1 911 %cmp1 = icmp eq i32 %and, 1 912 br i1 %cmp1, label %if.end, label %if.then 913 914if.then: ; preds = %for.body 915 call void @init() 916 br label %if.end 917 918if.end: ; preds = %if.then, %for.body 919 call void @sink() 920 %inc = add nuw nsw i32 %i.06, 1 921 %exitcond = icmp eq i32 %inc, %len 922 br i1 %exitcond, label %for.cond.cleanup, label %for.body 923} 924 925define void @test16__ivar_mod2_is_0(i32 %len) { 926; CHECK-LABEL: @test16__ivar_mod2_is_0( 927; CHECK-NEXT: entry: 928; CHECK-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[LEN:%.*]], 0 929; CHECK-NEXT: br i1 [[CMP5]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 930; CHECK: for.body.preheader: 931; CHECK-NEXT: br label [[FOR_BODY:%.*]] 932; CHECK: for.cond.cleanup.loopexit: 933; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 934; CHECK: for.cond.cleanup: 935; CHECK-NEXT: ret void 936; CHECK: for.body: 937; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ] 938; CHECK-NEXT: [[AND:%.*]] = and i32 [[I_06]], 1 939; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND]], 0 940; CHECK-NEXT: br i1 [[CMP1]], label [[IF_END]], label [[IF_THEN:%.*]] 941; CHECK: if.then: 942; CHECK-NEXT: call void @init() 943; CHECK-NEXT: br label [[IF_END]] 944; CHECK: if.end: 945; CHECK-NEXT: call void @sink() 946; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_06]], 1 947; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[LEN]] 948; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]] 949; 950entry: 951 %cmp5 = icmp sgt i32 %len, 0 952 br i1 %cmp5, label %for.body, label %for.cond.cleanup 953 954for.cond.cleanup: ; preds = %if.end, %entry 955 ret void 956 957for.body: ; preds = %entry, %if.end 958 %i.06 = phi i32 [ %inc, %if.end ], [ 0, %entry ] 959 %and = and i32 %i.06, 1 960 %cmp1 = icmp eq i32 %and, 0 961 br i1 %cmp1, label %if.end, label %if.then 962 963if.then: ; preds = %for.body 964 call void @init() 965 br label %if.end 966 967if.end: ; preds = %if.then, %for.body 968 call void @sink() 969 %inc = add nuw nsw i32 %i.06, 1 970 %exitcond = icmp eq i32 %inc, %len 971 br i1 %exitcond, label %for.cond.cleanup, label %for.body 972} 973 974declare void @init() 975declare void @sink() 976