1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -S -passes=loop-unroll -verify-loop-info | FileCheck %s 3; RUN: opt < %s -S -passes='require<opt-remark-emit>,loop-unroll,verify<loops>' | FileCheck %s 4; 5; Unit tests for LoopInfo::markAsRemoved. 6 7declare i1 @check() nounwind 8 9; Ensure that tail->inner is removed and rely on verify-loopinfo to 10; check soundness. 11define void @skiplevelexit() nounwind { 12; CHECK-LABEL: @skiplevelexit( 13; CHECK-NEXT: entry: 14; CHECK-NEXT: br label [[OUTER:%.*]] 15; CHECK: outer: 16; CHECK-NEXT: br label [[INNER:%.*]] 17; CHECK: inner: 18; CHECK-NEXT: [[TMP0:%.*]] = call zeroext i1 @check() 19; CHECK-NEXT: br i1 true, label [[OUTER_BACKEDGE:%.*]], label [[TAIL:%.*]] 20; CHECK: tail: 21; CHECK-NEXT: ret void 22; CHECK: outer.backedge: 23; CHECK-NEXT: br label [[OUTER]] 24; 25entry: 26 br label %outer 27 28outer: 29 br label %inner 30 31inner: 32 %iv = phi i32 [ 0, %outer ], [ %inc, %tail ] 33 %inc = add i32 %iv, 1 34 call zeroext i1 @check() 35 br i1 true, label %outer.backedge, label %tail 36 37tail: 38 br i1 false, label %inner, label %exit 39 40outer.backedge: 41 br label %outer 42 43exit: 44 ret void 45} 46 47; Remove the middle loop of a triply nested loop tree. 48; Ensure that only the middle loop is removed and rely on verify-loopinfo to 49; check soundness. 50define void @unloopNested() { 51; CHECK-LABEL: @unloopNested( 52; CHECK-NEXT: entry: 53; CHECK-NEXT: br label [[WHILE_COND_OUTER:%.*]] 54; CHECK: while.cond.outer: 55; CHECK-NEXT: br label [[WHILE_COND:%.*]] 56; CHECK: while.cond: 57; CHECK-NEXT: [[CMP:%.*]] = call zeroext i1 @check() 58; CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]] 59; CHECK: while.body: 60; CHECK-NEXT: [[CMP3:%.*]] = call zeroext i1 @check() 61; CHECK-NEXT: br i1 [[CMP3]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 62; CHECK: if.then: 63; CHECK-NEXT: br label [[RETURN:%.*]] 64; CHECK: if.end: 65; CHECK-NEXT: [[CMP_I48:%.*]] = call zeroext i1 @check() 66; CHECK-NEXT: br i1 [[CMP_I48]], label [[IF_THEN_I:%.*]], label [[IF_ELSE20_I:%.*]] 67; CHECK: if.then.i: 68; CHECK-NEXT: [[CMP8_I:%.*]] = call zeroext i1 @check() 69; CHECK-NEXT: br i1 [[CMP8_I]], label [[MERGE:%.*]], label [[IF_ELSE_I:%.*]] 70; CHECK: if.else.i: 71; CHECK-NEXT: br label [[MERGE]] 72; CHECK: if.else20.i: 73; CHECK-NEXT: [[CMP25_I:%.*]] = call zeroext i1 @check() 74; CHECK-NEXT: br i1 [[CMP25_I]], label [[MERGE]], label [[IF_ELSE28_I:%.*]] 75; CHECK: if.else28.i: 76; CHECK-NEXT: br label [[MERGE]] 77; CHECK: merge: 78; CHECK-NEXT: br label [[WHILE_COND2_I:%.*]] 79; CHECK: while.cond2.i: 80; CHECK-NEXT: [[CMP_I:%.*]] = call zeroext i1 @check() 81; CHECK-NEXT: br i1 [[CMP_I]], label [[WHILE_COND2_BACKEDGE_I:%.*]], label [[WHILE_END_I:%.*]] 82; CHECK: while.cond2.backedge.i: 83; CHECK-NEXT: br label [[WHILE_COND2_I]] 84; CHECK: while.end.i: 85; CHECK-NEXT: [[CMP1114_I:%.*]] = call zeroext i1 @check() 86; CHECK-NEXT: br i1 [[CMP1114_I]], label [[WHILE_BODY12_LR_PH_I:%.*]], label [[WHILE_END14_I:%.*]] 87; CHECK: while.body12.lr.ph.i: 88; CHECK-NEXT: br label [[WHILE_END14_I]] 89; CHECK: while.end14.i: 90; CHECK-NEXT: [[CALL15_I:%.*]] = call zeroext i1 @check() 91; CHECK-NEXT: br i1 [[CALL15_I]], label [[IF_END_I:%.*]], label [[EXIT:%.*]] 92; CHECK: if.end.i: 93; CHECK-NEXT: br label [[WHILE_COND2_BACKEDGE_I]] 94; CHECK: exit: 95; CHECK-NEXT: br label [[WHILE_COND_OUTER]] 96; CHECK: while.end: 97; CHECK-NEXT: br label [[RETURN]] 98; CHECK: return: 99; CHECK-NEXT: ret void 100; 101entry: 102 br label %while.cond.outer 103 104while.cond.outer: 105 br label %while.cond 106 107while.cond: 108 %cmp = call zeroext i1 @check() 109 br i1 %cmp, label %while.body, label %while.end 110 111while.body: 112 %cmp3 = call zeroext i1 @check() 113 br i1 %cmp3, label %if.then, label %if.end 114 115if.then: 116 br label %return 117 118if.end: 119 %cmp.i48 = call zeroext i1 @check() 120 br i1 %cmp.i48, label %if.then.i, label %if.else20.i 121 122if.then.i: 123 %cmp8.i = call zeroext i1 @check() 124 br i1 %cmp8.i, label %merge, label %if.else.i 125 126if.else.i: 127 br label %merge 128 129if.else20.i: 130 %cmp25.i = call zeroext i1 @check() 131 br i1 %cmp25.i, label %merge, label %if.else28.i 132 133if.else28.i: 134 br label %merge 135 136merge: 137 br label %while.cond2.i 138 139while.cond2.i: 140 %cmp.i = call zeroext i1 @check() 141 br i1 %cmp.i, label %while.cond2.backedge.i, label %while.end.i 142 143while.cond2.backedge.i: 144 br label %while.cond2.i 145 146while.end.i: 147 %cmp1114.i = call zeroext i1 @check() 148 br i1 %cmp1114.i, label %while.body12.lr.ph.i, label %while.end14.i 149 150while.body12.lr.ph.i: 151 br label %while.end14.i 152 153while.end14.i: 154 %call15.i = call zeroext i1 @check() 155 br i1 %call15.i, label %if.end.i, label %exit 156 157if.end.i: 158 br label %while.cond2.backedge.i 159 160exit: 161 br i1 false, label %while.cond, label %if.else 162 163if.else: 164 br label %while.cond.outer 165 166while.end: 167 br label %return 168 169return: 170 ret void 171} 172 173; Remove the middle loop of a deeply nested loop tree. 174; Ensure that only the middle loop is removed and rely on verify-loopinfo to 175; check soundness. 176; 177; This test must be disabled until trip count computation can be optimized... 178; rdar:14038809 [SCEV]: Optimize trip count computation for multi-exit loops. 179define void @unloopDeepNested() nounwind { 180; CHECK-LABEL: @unloopDeepNested( 181; CHECK-NEXT: for.cond8.preheader.i: 182; CHECK-NEXT: [[CMP113_I:%.*]] = call zeroext i1 @check() 183; CHECK-NEXT: br i1 [[CMP113_I]], label [[MAKE_DATA_EXIT:%.*]], label [[FOR_BODY13_LR_PH_I:%.*]] 184; CHECK: for.body13.lr.ph.i: 185; CHECK-NEXT: br label [[MAKE_DATA_EXIT]] 186; CHECK: make_data.exit: 187; CHECK-NEXT: br label [[WHILE_COND_OUTER_OUTER:%.*]] 188; CHECK: while.cond.outer.outer: 189; CHECK-NEXT: br label [[WHILE_COND_OUTER:%.*]] 190; CHECK: while.cond.outer: 191; CHECK-NEXT: br label [[WHILE_COND:%.*]] 192; CHECK: while.cond: 193; CHECK-NEXT: br label [[WHILE_COND_OUTER_I:%.*]] 194; CHECK: while.cond.outer.i: 195; CHECK-NEXT: [[TMP192_PH_I:%.*]] = call zeroext i1 @check() 196; CHECK-NEXT: br i1 [[TMP192_PH_I]], label [[WHILE_COND_OUTER_SPLIT_US_I:%.*]], label [[WHILE_BODY_LOOPEXIT:%.*]] 197; CHECK: while.cond.outer.split.us.i: 198; CHECK-NEXT: br label [[WHILE_COND_US_I:%.*]] 199; CHECK: while.cond.us.i: 200; CHECK-NEXT: [[CMP_US_I:%.*]] = call zeroext i1 @check() 201; CHECK-NEXT: br i1 [[CMP_US_I]], label [[NEXT_DATA_EXIT:%.*]], label [[WHILE_BODY_US_I:%.*]] 202; CHECK: while.body.us.i: 203; CHECK-NEXT: [[CMP7_US_I:%.*]] = call zeroext i1 @check() 204; CHECK-NEXT: br i1 [[CMP7_US_I]], label [[IF_THEN_US_I:%.*]], label [[IF_ELSE_I:%.*]] 205; CHECK: if.then.us.i: 206; CHECK-NEXT: br label [[WHILE_COND_US_I]] 207; CHECK: if.else.i: 208; CHECK-NEXT: br label [[WHILE_COND_OUTER_I]] 209; CHECK: next_data.exit: 210; CHECK-NEXT: [[TMP192_PH_I_LCSSA28:%.*]] = call zeroext i1 @check() 211; CHECK-NEXT: br i1 [[TMP192_PH_I_LCSSA28]], label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]] 212; CHECK: while.body.loopexit: 213; CHECK-NEXT: br label [[WHILE_BODY]] 214; CHECK: while.body: 215; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 216; CHECK: while.cond.i: 217; CHECK-NEXT: [[CMP_I:%.*]] = call zeroext i1 @check() 218; CHECK-NEXT: br i1 [[CMP_I]], label [[VALID_DATA_EXIT:%.*]], label [[WHILE_BODY_I:%.*]] 219; CHECK: while.body.i: 220; CHECK-NEXT: [[CMP7_I:%.*]] = call zeroext i1 @check() 221; CHECK-NEXT: br i1 [[CMP7_I]], label [[VALID_DATA_EXIT]], label [[IF_END_I:%.*]] 222; CHECK: if.end.i: 223; CHECK-NEXT: br label [[WHILE_COND_I]] 224; CHECK: valid_data.exit: 225; CHECK-NEXT: [[CMP:%.*]] = call zeroext i1 @check() 226; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN12:%.*]], label [[IF_END:%.*]] 227; CHECK: if.then12: 228; CHECK-NEXT: br label [[IF_END]] 229; CHECK: if.end: 230; CHECK-NEXT: [[TOBOOL3_I:%.*]] = call zeroext i1 @check() 231; CHECK-NEXT: br i1 [[TOBOOL3_I]], label [[COPY_DATA_EXIT:%.*]], label [[WHILE_BODY_LR_PH_I:%.*]] 232; CHECK: while.body.lr.ph.i: 233; CHECK-NEXT: br label [[COPY_DATA_EXIT]] 234; CHECK: copy_data.exit: 235; CHECK-NEXT: [[CMP38:%.*]] = call zeroext i1 @check() 236; CHECK-NEXT: br i1 [[CMP38]], label [[IF_THEN39:%.*]], label [[WHILE_COND_OUTER]] 237; CHECK: if.then39: 238; CHECK-NEXT: [[CMP5_I:%.*]] = call zeroext i1 @check() 239; CHECK-NEXT: br i1 [[CMP5_I]], label [[WHILE_COND_OUTER_OUTER_BACKEDGE:%.*]], label [[FOR_COND8_PREHEADER_I8_THREAD:%.*]] 240; CHECK: for.cond8.preheader.i8.thread: 241; CHECK-NEXT: br label [[WHILE_COND_OUTER_OUTER_BACKEDGE]] 242; CHECK: while.cond.outer.outer.backedge: 243; CHECK-NEXT: br label [[WHILE_COND_OUTER_OUTER]] 244; CHECK: while.end: 245; CHECK-NEXT: ret void 246; 247for.cond8.preheader.i: 248 %cmp113.i = call zeroext i1 @check() 249 br i1 %cmp113.i, label %make_data.exit, label %for.body13.lr.ph.i 250 251for.body13.lr.ph.i: 252 br label %make_data.exit 253 254make_data.exit: 255 br label %while.cond.outer.outer 256 257while.cond.outer.outer: 258 br label %while.cond.outer 259 260while.cond.outer: 261 br label %while.cond 262 263while.cond: 264 br label %while.cond.outer.i 265 266while.cond.outer.i: 267 %tmp192.ph.i = call zeroext i1 @check() 268 br i1 %tmp192.ph.i, label %while.cond.outer.split.us.i, label %while.body.loopexit 269 270while.cond.outer.split.us.i: 271 br label %while.cond.us.i 272 273while.cond.us.i: 274 %cmp.us.i = call zeroext i1 @check() 275 br i1 %cmp.us.i, label %next_data.exit, label %while.body.us.i 276 277while.body.us.i: 278 %cmp7.us.i = call zeroext i1 @check() 279 br i1 %cmp7.us.i, label %if.then.us.i, label %if.else.i 280 281if.then.us.i: 282 br label %while.cond.us.i 283 284if.else.i: 285 br label %while.cond.outer.i 286 287next_data.exit: 288 %tmp192.ph.i.lcssa28 = call zeroext i1 @check() 289 br i1 %tmp192.ph.i.lcssa28, label %while.end, label %while.body 290 291while.body.loopexit: 292 br label %while.body 293 294while.body: 295 br label %while.cond.i 296 297while.cond.i: 298 %cmp.i = call zeroext i1 @check() 299 br i1 %cmp.i, label %valid_data.exit, label %while.body.i 300 301while.body.i: 302 %cmp7.i = call zeroext i1 @check() 303 br i1 %cmp7.i, label %valid_data.exit, label %if.end.i 304 305if.end.i: 306 br label %while.cond.i 307 308valid_data.exit: 309 br i1 true, label %if.then, label %while.cond 310 311if.then: 312 %cmp = call zeroext i1 @check() 313 br i1 %cmp, label %if.then12, label %if.end 314 315if.then12: 316 br label %if.end 317 318if.end: 319 %tobool3.i = call zeroext i1 @check() 320 br i1 %tobool3.i, label %copy_data.exit, label %while.body.lr.ph.i 321 322while.body.lr.ph.i: 323 br label %copy_data.exit 324 325copy_data.exit: 326 %cmp38 = call zeroext i1 @check() 327 br i1 %cmp38, label %if.then39, label %while.cond.outer 328 329if.then39: 330 %cmp5.i = call zeroext i1 @check() 331 br i1 %cmp5.i, label %while.cond.outer.outer.backedge, label %for.cond8.preheader.i8.thread 332 333for.cond8.preheader.i8.thread: 334 br label %while.cond.outer.outer.backedge 335 336while.cond.outer.outer.backedge: 337 br label %while.cond.outer.outer 338 339while.end: 340 ret void 341} 342 343; Remove a nested loop with irreducible control flow. 344; Ensure that only the middle loop is removed and rely on verify-loopinfo to 345; check soundness. 346define void @unloopIrreducible() nounwind { 347; CHECK-LABEL: @unloopIrreducible( 348; CHECK-NEXT: entry: 349; CHECK-NEXT: br label [[FOR_BODY:%.*]] 350; CHECK: for.body: 351; CHECK-NEXT: [[CMP2113:%.*]] = call zeroext i1 @check() 352; CHECK-NEXT: br i1 [[CMP2113]], label [[FOR_BODY22_LR_PH:%.*]], label [[FOR_INC163:%.*]] 353; CHECK: for.body22.lr.ph: 354; CHECK-NEXT: br label [[FOR_BODY22:%.*]] 355; CHECK: for.body22: 356; CHECK-NEXT: br label [[FOR_BODY33:%.*]] 357; CHECK: for.body33: 358; CHECK-NEXT: br label [[FOR_END:%.*]] 359; CHECK: for.end: 360; CHECK-NEXT: [[CMP424:%.*]] = call zeroext i1 @check() 361; CHECK-NEXT: br i1 [[CMP424]], label [[FOR_BODY43_LR_PH:%.*]], label [[FOR_END93:%.*]] 362; CHECK: for.body43.lr.ph: 363; CHECK-NEXT: br label [[FOR_END93]] 364; CHECK: for.end93: 365; CHECK-NEXT: [[CMP96:%.*]] = call zeroext i1 @check() 366; CHECK-NEXT: br i1 [[CMP96]], label [[IF_THEN97:%.*]], label [[FOR_COND103:%.*]] 367; CHECK: if.then97: 368; CHECK-NEXT: br label [[FOR_COND103T:%.*]] 369; CHECK: for.cond103t: 370; CHECK-NEXT: br label [[FOR_COND103]] 371; CHECK: for.cond103: 372; CHECK-NEXT: [[CMP105:%.*]] = call zeroext i1 @check() 373; CHECK-NEXT: br i1 [[CMP105]], label [[FOR_BODY106:%.*]], label [[FOR_END120:%.*]] 374; CHECK: for.body106: 375; CHECK-NEXT: [[CMP108:%.*]] = call zeroext i1 @check() 376; CHECK-NEXT: br i1 [[CMP108]], label [[IF_THEN109:%.*]], label [[FOR_INC117:%.*]] 377; CHECK: if.then109: 378; CHECK-NEXT: br label [[FOR_INC117]] 379; CHECK: for.inc117: 380; CHECK-NEXT: br label [[FOR_COND103T]] 381; CHECK: for.end120: 382; CHECK-NEXT: br label [[FOR_INC159:%.*]] 383; CHECK: for.inc159: 384; CHECK-NEXT: br label [[FOR_INC163]] 385; CHECK: for.inc163: 386; CHECK-NEXT: [[CMP12:%.*]] = call zeroext i1 @check() 387; CHECK-NEXT: br i1 [[CMP12]], label [[FOR_BODY]], label [[FOR_END166:%.*]] 388; CHECK: for.end166: 389; CHECK-NEXT: ret void 390; 391entry: 392 br label %for.body 393 394for.body: 395 %cmp2113 = call zeroext i1 @check() 396 br i1 %cmp2113, label %for.body22.lr.ph, label %for.inc163 397 398for.body22.lr.ph: 399 br label %for.body22 400 401for.body22: 402 br label %for.body33 403 404for.body33: 405 br label %for.end 406 407for.end: 408 %cmp424 = call zeroext i1 @check() 409 br i1 %cmp424, label %for.body43.lr.ph, label %for.end93 410 411for.body43.lr.ph: 412 br label %for.end93 413 414for.end93: 415 %cmp96 = call zeroext i1 @check() 416 br i1 %cmp96, label %if.then97, label %for.cond103 417 418if.then97: 419 br label %for.cond103t 420 421for.cond103t: 422 br label %for.cond103 423 424for.cond103: 425 %cmp105 = call zeroext i1 @check() 426 br i1 %cmp105, label %for.body106, label %for.end120 427 428for.body106: 429 %cmp108 = call zeroext i1 @check() 430 br i1 %cmp108, label %if.then109, label %for.inc117 431 432if.then109: 433 br label %for.inc117 434 435for.inc117: 436 br label %for.cond103t 437 438for.end120: 439 br label %for.inc159 440 441for.inc159: 442 br i1 false, label %for.body22, label %for.cond15.for.inc163_crit_edge 443 444for.cond15.for.inc163_crit_edge: 445 br label %for.inc163 446 447for.inc163: 448 %cmp12 = call zeroext i1 @check() 449 br i1 %cmp12, label %for.body, label %for.end166 450 451for.end166: 452 ret void 453 454} 455 456; Remove a loop whose exit branches into a sibling loop. 457; Ensure that only the loop is removed and rely on verify-loopinfo to 458; check soundness. 459define void @unloopCriticalEdge(i1 %arg) nounwind { 460; CHECK-LABEL: @unloopCriticalEdge( 461; CHECK-NEXT: entry: 462; CHECK-NEXT: br label [[FOR_COND31:%.*]] 463; CHECK: for.cond31: 464; CHECK-NEXT: br i1 false, label [[FOR_BODY35:%.*]], label [[FOR_END94:%.*]] 465; CHECK: for.body35: 466; CHECK-NEXT: br label [[WHILE_COND_I_PREHEADER:%.*]] 467; CHECK: while.cond.i.preheader: 468; CHECK-NEXT: br i1 %arg, label [[WHILE_COND_I_PREHEADER_SPLIT:%.*]], label [[WHILE_COND_OUTER_I_LOOPEXIT_SPLIT:%.*]] 469; CHECK: while.cond.i.preheader.split: 470; CHECK-NEXT: br label [[WHILE_COND_I:%.*]] 471; CHECK: while.cond.i: 472; CHECK-NEXT: br i1 true, label [[WHILE_COND_I]], label [[WHILE_COND_OUTER_I_LOOPEXIT:%.*]] 473; CHECK: while.cond.outer.i.loopexit: 474; CHECK-NEXT: br label [[WHILE_COND_OUTER_I_LOOPEXIT_SPLIT]] 475; CHECK: while.cond.outer.i.loopexit.split: 476; CHECK-NEXT: br label [[WHILE_BODY:%.*]] 477; CHECK: while.body: 478; CHECK-NEXT: br label [[FOR_END78:%.*]] 479; CHECK: for.end78: 480; CHECK-NEXT: br i1 false, label [[PROC2_EXIT:%.*]], label [[FOR_COND_I_PREHEADER:%.*]] 481; CHECK: for.cond.i.preheader: 482; CHECK-NEXT: br label [[FOR_COND_I:%.*]] 483; CHECK: for.cond.i: 484; CHECK-NEXT: br label [[FOR_COND_I]] 485; CHECK: Proc2.exit: 486; CHECK-NEXT: unreachable 487; CHECK: for.end94: 488; CHECK-NEXT: ret void 489; 490entry: 491 br label %for.cond31 492 493for.cond31: 494 br i1 false, label %for.body35, label %for.end94 495 496for.body35: 497 br label %while.cond.i.preheader 498 499while.cond.i.preheader: 500 br i1 %arg, label %while.cond.i.preheader.split, label %while.cond.outer.i.loopexit.split 501 502while.cond.i.preheader.split: 503 br label %while.cond.i 504 505while.cond.i: 506 br i1 true, label %while.cond.i, label %while.cond.outer.i.loopexit 507 508while.cond.outer.i.loopexit: 509 br label %while.cond.outer.i.loopexit.split 510 511while.cond.outer.i.loopexit.split: 512 br i1 false, label %while.cond.i.preheader, label %Func2.exit 513 514Func2.exit: 515 br label %while.body 516 517while.body: 518 br i1 false, label %while.body, label %while.end 519 520while.end: 521 br label %for.end78 522 523for.end78: 524 br i1 false, label %Proc2.exit, label %for.cond.i.preheader 525 526for.cond.i.preheader: 527 br label %for.cond.i 528 529for.cond.i: 530 br label %for.cond.i 531 532Proc2.exit: 533 br label %for.cond31 534 535for.end94: 536 ret void 537} 538 539; Test UnloopUpdater::removeBlocksFromAncestors. 540; 541; Check that the loop backedge is removed from the middle loop 1699, 542; but not the inner loop 1676. 543define void @removeSubloopBlocks() nounwind { 544; CHECK-LABEL: @removeSubloopBlocks( 545; CHECK-NEXT: entry: 546; CHECK-NEXT: br label [[TRYAGAIN_OUTER:%.*]] 547; CHECK: tryagain.outer: 548; CHECK-NEXT: br label [[TRYAGAIN:%.*]] 549; CHECK: tryagain: 550; CHECK-NEXT: br i1 false, label [[SW_BB1669:%.*]], label [[SW_BB304:%.*]] 551; CHECK: sw.bb304: 552; CHECK-NEXT: ret void 553; CHECK: sw.bb1669: 554; CHECK-NEXT: br i1 true, label [[SW_DEFAULT1711:%.*]], label [[WHILE_COND1676_PREHEADER:%.*]] 555; CHECK: while.cond1676.preheader: 556; CHECK-NEXT: br label [[WHILE_COND1676:%.*]] 557; CHECK: while.cond1676: 558; CHECK-NEXT: br i1 true, label [[WHILE_END1699:%.*]], label [[WHILE_BODY1694:%.*]] 559; CHECK: while.body1694: 560; CHECK-NEXT: unreachable 561; CHECK: while.end1699: 562; CHECK-NEXT: br label [[SW_DEFAULT1711]] 563; CHECK: sw.default1711: 564; CHECK-NEXT: br label [[DEFCHAR:%.*]] 565; CHECK: defchar: 566; CHECK-NEXT: br i1 true, label [[IF_END2413:%.*]], label [[IF_THEN2368:%.*]] 567; CHECK: if.then2368: 568; CHECK-NEXT: unreachable 569; CHECK: if.end2413: 570; CHECK-NEXT: unreachable 571; 572entry: 573 br label %tryagain.outer 574 575tryagain.outer: ; preds = %sw.bb304, %entry 576 br label %tryagain 577 578tryagain: ; preds = %while.end1699, %tryagain.outer 579 br i1 false, label %sw.bb1669, label %sw.bb304 580 581sw.bb304: ; preds = %tryagain 582 br i1 true, label %return, label %tryagain.outer 583 584sw.bb1669: ; preds = %tryagain 585 br i1 true, label %sw.default1711, label %while.cond1676 586 587while.cond1676: ; preds = %while.body1694, %sw.bb1669 588 br i1 true, label %while.end1699, label %while.body1694 589 590while.body1694: ; preds = %while.cond1676 591 br label %while.cond1676 592 593while.end1699: ; preds = %while.cond1676 594 br i1 false, label %tryagain, label %sw.default1711 595 596sw.default1711: ; preds = %while.end1699, %sw.bb1669, %tryagain 597 br label %defchar 598 599defchar: ; preds = %sw.default1711, %sw.bb376 600 br i1 true, label %if.end2413, label %if.then2368 601 602if.then2368: ; preds = %defchar 603 unreachable 604 605if.end2413: ; preds = %defchar 606 unreachable 607 608return: ; preds = %sw.bb304 609 ret void 610} 611 612; PR11335: the most deeply nested block should be removed from the outer loop. 613define void @removeSubloopBlocks2() nounwind { 614; CHECK-LABEL: @removeSubloopBlocks2( 615; CHECK-NEXT: entry: 616; CHECK-NEXT: [[TOBOOL_I:%.*]] = icmp ne i32 undef, 0 617; CHECK-NEXT: br label [[LBL_616:%.*]] 618; CHECK: lbl_616.loopexit: 619; CHECK-NEXT: br label [[LBL_616]] 620; CHECK: lbl_616: 621; CHECK-NEXT: br label [[FOR_COND:%.*]] 622; CHECK: for.cond: 623; CHECK-NEXT: br i1 false, label [[FOR_COND1_PREHEADER:%.*]], label [[LBL_616_LOOPEXIT:%.*]] 624; CHECK: for.cond1.preheader: 625; CHECK-NEXT: br label [[FOR_COND1:%.*]] 626; CHECK: for.cond1.loopexit: 627; CHECK-NEXT: unreachable 628; CHECK: for.cond1: 629; CHECK-NEXT: br i1 false, label [[FOR_BODY2:%.*]], label [[FOR_COND3:%.*]] 630; CHECK: for.body2: 631; CHECK-NEXT: br label [[FOR_COND_I:%.*]] 632; CHECK: for.cond.i: 633; CHECK-NEXT: br i1 [[TOBOOL_I]], label [[FOR_COND_I]], label [[FOR_COND1_LOOPEXIT:%.*]] 634; CHECK: for.cond3: 635; CHECK-NEXT: ret void 636; 637entry: 638 %tobool.i = icmp ne i32 undef, 0 639 br label %lbl_616 640 641lbl_616.loopexit: ; preds = %for.cond 642 br label %lbl_616 643 644lbl_616: ; preds = %lbl_616.loopexit, %entry 645 br label %for.cond 646 647for.cond: ; preds = %for.cond3, %lbl_616 648 br i1 false, label %for.cond1.preheader, label %lbl_616.loopexit 649 650for.cond1.preheader: ; preds = %for.cond 651 br label %for.cond1 652 653for.cond1.loopexit: ; preds = %for.cond.i 654 br label %for.cond1 655 656for.cond1: ; preds = %for.cond1.loopexit, %for.cond1.preheader 657 br i1 false, label %for.body2, label %for.cond3 658 659for.body2: ; preds = %for.cond1 660 br label %for.cond.i 661 662for.cond.i: ; preds = %for.cond.i, %for.body2 663 br i1 %tobool.i, label %for.cond.i, label %for.cond1.loopexit 664 665for.cond3: ; preds = %for.cond1 666 br i1 false, label %for.cond, label %if.end 667 668if.end: ; preds = %for.cond3 669 ret void 670} 671