1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -mtriple=thumbv8m.main -passes='simple-loop-unswitch<nontrivial>' -unswitch-threshold=5 -S -o - %s | FileCheck %s 3 4declare void @a() 5declare void @b() 6declare void @x() 7 8define void @test_no_unswitch(ptr %ptr, i1 %cond) { 9; CHECK-LABEL: @test_no_unswitch( 10; CHECK-NEXT: entry: 11; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] 12; CHECK: loop_begin: 13; CHECK-NEXT: call void @x() 14; CHECK-NEXT: call void @x() 15; CHECK-NEXT: call void @x() 16; CHECK-NEXT: call void @x() 17; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]] 18; CHECK: loop_a: 19; CHECK-NEXT: call void @a() 20; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] 21; CHECK: loop_b: 22; CHECK-NEXT: call void @b() 23; CHECK-NEXT: br label [[LOOP_LATCH]] 24; CHECK: loop_latch: 25; CHECK-NEXT: [[V:%.*]] = load i1, ptr [[PTR:%.*]], align 1 26; CHECK-NEXT: br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]] 27; CHECK: loop_exit: 28; CHECK-NEXT: ret void 29; 30entry: 31 br label %loop_begin 32loop_begin: 33 call void @x() 34 call void @x() 35 call void @x() 36 call void @x() 37 br i1 %cond, label %loop_a, label %loop_b 38 39loop_a: 40 call void @a() 41 br label %loop_latch 42 43loop_b: 44 call void @b() 45 br label %loop_latch 46 47loop_latch: 48 %v = load i1, ptr %ptr 49 br i1 %v, label %loop_begin, label %loop_exit 50 51loop_exit: 52 ret void 53} 54 55define void @test_unswitch(ptr %ptr, i1 %cond) { 56; CHECK-LABEL: @test_unswitch( 57; CHECK-NEXT: entry: 58; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND:%.*]] 59; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 60; CHECK: entry.split.us: 61; CHECK-NEXT: br label [[LOOP_BEGIN_US:%.*]] 62; CHECK: loop_begin.us: 63; CHECK-NEXT: call void @x() 64; CHECK-NEXT: br label [[LOOP_A_US:%.*]] 65; CHECK: loop_a.us: 66; CHECK-NEXT: call void @a() 67; CHECK-NEXT: br label [[LOOP_LATCH_US:%.*]] 68; CHECK: loop_latch.us: 69; CHECK-NEXT: [[V_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1 70; CHECK-NEXT: br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]] 71; CHECK: loop_exit.split.us: 72; CHECK-NEXT: br label [[LOOP_EXIT:%.*]] 73; CHECK: entry.split: 74; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] 75; CHECK: loop_begin: 76; CHECK-NEXT: call void @x() 77; CHECK-NEXT: br label [[LOOP_B:%.*]] 78; CHECK: loop_b: 79; CHECK-NEXT: call void @b() 80; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] 81; CHECK: loop_latch: 82; CHECK-NEXT: [[V:%.*]] = load i1, ptr [[PTR]], align 1 83; CHECK-NEXT: br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]] 84; CHECK: loop_exit.split: 85; CHECK-NEXT: br label [[LOOP_EXIT]] 86; CHECK: loop_exit: 87; CHECK-NEXT: ret void 88; 89entry: 90 br label %loop_begin 91 92loop_begin: 93 call void @x() 94 br i1 %cond, label %loop_a, label %loop_b 95 96loop_a: 97 call void @a() 98 br label %loop_latch 99 100loop_b: 101 call void @b() 102 br label %loop_latch 103 104loop_latch: 105 %v = load i1, ptr %ptr 106 br i1 %v, label %loop_begin, label %loop_exit 107 108loop_exit: 109 ret void 110} 111 112define void @test_unswitch_minsize(ptr %ptr, i1 %cond) #0 { 113; CHECK-LABEL: @test_unswitch_minsize( 114; CHECK-NEXT: entry: 115; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] 116; CHECK: loop_begin: 117; CHECK-NEXT: call void @x() 118; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]] 119; CHECK: loop_a: 120; CHECK-NEXT: call void @a() 121; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] 122; CHECK: loop_b: 123; CHECK-NEXT: call void @b() 124; CHECK-NEXT: br label [[LOOP_LATCH]] 125; CHECK: loop_latch: 126; CHECK-NEXT: [[V:%.*]] = load i1, ptr [[PTR:%.*]], align 1 127; CHECK-NEXT: br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]] 128; CHECK: loop_exit: 129; CHECK-NEXT: ret void 130; 131entry: 132 br label %loop_begin 133 134loop_begin: 135 call void @x() 136 br i1 %cond, label %loop_a, label %loop_b 137 138loop_a: 139 call void @a() 140 br label %loop_latch 141 142loop_b: 143 call void @b() 144 br label %loop_latch 145 146loop_latch: 147 %v = load i1, ptr %ptr 148 br i1 %v, label %loop_begin, label %loop_exit 149 150loop_exit: 151 ret void 152} 153 154define void @test_unswitch_non_dup_code(ptr %ptr, i1 %cond) { 155; CHECK-LABEL: @test_unswitch_non_dup_code( 156; CHECK-NEXT: entry: 157; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND:%.*]] 158; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 159; CHECK: entry.split.us: 160; CHECK-NEXT: br label [[LOOP_BEGIN_US:%.*]] 161; CHECK: loop_begin.us: 162; CHECK-NEXT: call void @x() 163; CHECK-NEXT: br label [[LOOP_A_US:%.*]] 164; CHECK: loop_a.us: 165; CHECK-NEXT: call void @a() 166; CHECK-NEXT: call void @a() 167; CHECK-NEXT: call void @a() 168; CHECK-NEXT: call void @a() 169; CHECK-NEXT: br label [[LOOP_LATCH_US:%.*]] 170; CHECK: loop_latch.us: 171; CHECK-NEXT: [[V_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1 172; CHECK-NEXT: br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]] 173; CHECK: loop_exit.split.us: 174; CHECK-NEXT: br label [[LOOP_EXIT:%.*]] 175; CHECK: entry.split: 176; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] 177; CHECK: loop_begin: 178; CHECK-NEXT: call void @x() 179; CHECK-NEXT: br label [[LOOP_B:%.*]] 180; CHECK: loop_b: 181; CHECK-NEXT: call void @b() 182; CHECK-NEXT: call void @b() 183; CHECK-NEXT: call void @b() 184; CHECK-NEXT: call void @b() 185; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] 186; CHECK: loop_latch: 187; CHECK-NEXT: [[V:%.*]] = load i1, ptr [[PTR]], align 1 188; CHECK-NEXT: br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]] 189; CHECK: loop_exit.split: 190; CHECK-NEXT: br label [[LOOP_EXIT]] 191; CHECK: loop_exit: 192; CHECK-NEXT: ret void 193; 194entry: 195 br label %loop_begin 196 197loop_begin: 198 call void @x() 199 br i1 %cond, label %loop_a, label %loop_b 200 201loop_a: 202 call void @a() 203 call void @a() 204 call void @a() 205 call void @a() 206 br label %loop_latch 207 208loop_b: 209 call void @b() 210 call void @b() 211 call void @b() 212 call void @b() 213 br label %loop_latch 214 215loop_latch: 216 %v = load i1, ptr %ptr 217 br i1 %v, label %loop_begin, label %loop_exit 218 219loop_exit: 220 ret void 221} 222 223define void @test_unswitch_non_dup_code_minsize(ptr %ptr, i1 %cond) #0 { 224; CHECK-LABEL: @test_unswitch_non_dup_code_minsize( 225; CHECK-NEXT: entry: 226; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] 227; CHECK: loop_begin: 228; CHECK-NEXT: call void @x() 229; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]] 230; CHECK: loop_a: 231; CHECK-NEXT: call void @a() 232; CHECK-NEXT: call void @a() 233; CHECK-NEXT: call void @a() 234; CHECK-NEXT: call void @a() 235; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] 236; CHECK: loop_b: 237; CHECK-NEXT: call void @b() 238; CHECK-NEXT: call void @b() 239; CHECK-NEXT: call void @b() 240; CHECK-NEXT: call void @b() 241; CHECK-NEXT: br label [[LOOP_LATCH]] 242; CHECK: loop_latch: 243; CHECK-NEXT: [[V:%.*]] = load i1, ptr [[PTR:%.*]], align 1 244; CHECK-NEXT: br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]] 245; CHECK: loop_exit: 246; CHECK-NEXT: ret void 247; 248entry: 249 br label %loop_begin 250 251loop_begin: 252 call void @x() 253 br i1 %cond, label %loop_a, label %loop_b 254 255loop_a: 256 call void @a() 257 call void @a() 258 call void @a() 259 call void @a() 260 br label %loop_latch 261 262loop_b: 263 call void @b() 264 call void @b() 265 call void @b() 266 call void @b() 267 br label %loop_latch 268 269loop_latch: 270 %v = load i1, ptr %ptr 271 br i1 %v, label %loop_begin, label %loop_exit 272 273loop_exit: 274 ret void 275} 276 277define void @test_unswitch_non_dup_code_in_cfg(ptr %ptr, i1 %cond) { 278; CHECK-LABEL: @test_unswitch_non_dup_code_in_cfg( 279; CHECK-NEXT: entry: 280; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND:%.*]] 281; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 282; CHECK: entry.split.us: 283; CHECK-NEXT: br label [[LOOP_BEGIN_US:%.*]] 284; CHECK: loop_begin.us: 285; CHECK-NEXT: call void @x() 286; CHECK-NEXT: br label [[LOOP_A_US:%.*]] 287; CHECK: loop_a.us: 288; CHECK-NEXT: [[V1_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1 289; CHECK-NEXT: br i1 [[V1_US]], label [[LOOP_A_A_US:%.*]], label [[LOOP_A_B_US:%.*]] 290; CHECK: loop_a_b.us: 291; CHECK-NEXT: call void @a() 292; CHECK-NEXT: br label [[LOOP_LATCH_US:%.*]] 293; CHECK: loop_a_a.us: 294; CHECK-NEXT: call void @a() 295; CHECK-NEXT: br label [[LOOP_LATCH_US]] 296; CHECK: loop_latch.us: 297; CHECK-NEXT: [[V3_US:%.*]] = load i1, ptr [[PTR]], align 1 298; CHECK-NEXT: br i1 [[V3_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]] 299; CHECK: loop_exit.split.us: 300; CHECK-NEXT: br label [[LOOP_EXIT:%.*]] 301; CHECK: entry.split: 302; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] 303; CHECK: loop_begin: 304; CHECK-NEXT: call void @x() 305; CHECK-NEXT: br label [[LOOP_B:%.*]] 306; CHECK: loop_b: 307; CHECK-NEXT: [[V2:%.*]] = load i1, ptr [[PTR]], align 1 308; CHECK-NEXT: br i1 [[V2]], label [[LOOP_B_A:%.*]], label [[LOOP_B_B:%.*]] 309; CHECK: loop_b_a: 310; CHECK-NEXT: call void @b() 311; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] 312; CHECK: loop_b_b: 313; CHECK-NEXT: call void @b() 314; CHECK-NEXT: br label [[LOOP_LATCH]] 315; CHECK: loop_latch: 316; CHECK-NEXT: [[V3:%.*]] = load i1, ptr [[PTR]], align 1 317; CHECK-NEXT: br i1 [[V3]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]] 318; CHECK: loop_exit.split: 319; CHECK-NEXT: br label [[LOOP_EXIT]] 320; CHECK: loop_exit: 321; CHECK-NEXT: ret void 322; 323entry: 324 br label %loop_begin 325 326loop_begin: 327 call void @x() 328 br i1 %cond, label %loop_a, label %loop_b 329 330loop_a: 331 %v1 = load i1, ptr %ptr 332 br i1 %v1, label %loop_a_a, label %loop_a_b 333 334loop_a_a: 335 call void @a() 336 br label %loop_latch 337 338loop_a_b: 339 call void @a() 340 br label %loop_latch 341 342loop_b: 343 %v2 = load i1, ptr %ptr 344 br i1 %v2, label %loop_b_a, label %loop_b_b 345 346loop_b_a: 347 call void @b() 348 br label %loop_latch 349 350loop_b_b: 351 call void @b() 352 br label %loop_latch 353 354loop_latch: 355 %v3 = load i1, ptr %ptr 356 br i1 %v3, label %loop_begin, label %loop_exit 357 358loop_exit: 359 ret void 360} 361 362define void @test_unswitch_non_dup_code_in_cfg_minsize(ptr %ptr, i1 %cond) #0 { 363; CHECK-LABEL: @test_unswitch_non_dup_code_in_cfg_minsize( 364; CHECK-NEXT: entry: 365; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] 366; CHECK: loop_begin: 367; CHECK-NEXT: call void @x() 368; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]] 369; CHECK: loop_a: 370; CHECK-NEXT: [[V1:%.*]] = load i1, ptr [[PTR:%.*]], align 1 371; CHECK-NEXT: br i1 [[V1]], label [[LOOP_A_A:%.*]], label [[LOOP_A_B:%.*]] 372; CHECK: loop_a_a: 373; CHECK-NEXT: call void @a() 374; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] 375; CHECK: loop_a_b: 376; CHECK-NEXT: call void @a() 377; CHECK-NEXT: br label [[LOOP_LATCH]] 378; CHECK: loop_b: 379; CHECK-NEXT: [[V2:%.*]] = load i1, ptr [[PTR]], align 1 380; CHECK-NEXT: br i1 [[V2]], label [[LOOP_B_A:%.*]], label [[LOOP_B_B:%.*]] 381; CHECK: loop_b_a: 382; CHECK-NEXT: call void @b() 383; CHECK-NEXT: br label [[LOOP_LATCH]] 384; CHECK: loop_b_b: 385; CHECK-NEXT: call void @b() 386; CHECK-NEXT: br label [[LOOP_LATCH]] 387; CHECK: loop_latch: 388; CHECK-NEXT: [[V3:%.*]] = load i1, ptr [[PTR]], align 1 389; CHECK-NEXT: br i1 [[V3]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]] 390; CHECK: loop_exit: 391; CHECK-NEXT: ret void 392; 393entry: 394 br label %loop_begin 395 396loop_begin: 397 call void @x() 398 br i1 %cond, label %loop_a, label %loop_b 399 400loop_a: 401 %v1 = load i1, ptr %ptr 402 br i1 %v1, label %loop_a_a, label %loop_a_b 403 404loop_a_a: 405 call void @a() 406 br label %loop_latch 407 408loop_a_b: 409 call void @a() 410 br label %loop_latch 411 412loop_b: 413 %v2 = load i1, ptr %ptr 414 br i1 %v2, label %loop_b_a, label %loop_b_b 415 416loop_b_a: 417 call void @b() 418 br label %loop_latch 419 420loop_b_b: 421 call void @b() 422 br label %loop_latch 423 424loop_latch: 425 %v3 = load i1, ptr %ptr 426 br i1 %v3, label %loop_begin, label %loop_exit 427 428loop_exit: 429 ret void 430} 431 432define void @test_no_unswitch_non_dup_code(ptr %ptr, i1 %cond) { 433; CHECK-LABEL: @test_no_unswitch_non_dup_code( 434; CHECK-NEXT: entry: 435; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] 436; CHECK: loop_begin: 437; CHECK-NEXT: call void @x() 438; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]] 439; CHECK: loop_a: 440; CHECK-NEXT: [[V1:%.*]] = load i1, ptr [[PTR:%.*]], align 1 441; CHECK-NEXT: br i1 [[V1]], label [[LOOP_A_A:%.*]], label [[LOOP_A_B:%.*]] 442; CHECK: loop_a_a: 443; CHECK-NEXT: call void @a() 444; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] 445; CHECK: loop_a_b: 446; CHECK-NEXT: call void @a() 447; CHECK-NEXT: br label [[LOOP_LATCH]] 448; CHECK: loop_b: 449; CHECK-NEXT: [[V2:%.*]] = load i1, ptr [[PTR]], align 1 450; CHECK-NEXT: br i1 [[V2]], label [[LOOP_B_A:%.*]], label [[LOOP_B_B:%.*]] 451; CHECK: loop_b_a: 452; CHECK-NEXT: call void @b() 453; CHECK-NEXT: br label [[LOOP_LATCH]] 454; CHECK: loop_b_b: 455; CHECK-NEXT: call void @b() 456; CHECK-NEXT: br label [[LOOP_LATCH]] 457; CHECK: loop_latch: 458; CHECK-NEXT: call void @x() 459; CHECK-NEXT: call void @x() 460; CHECK-NEXT: [[V:%.*]] = load i1, ptr [[PTR]], align 1 461; CHECK-NEXT: br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]] 462; CHECK: loop_exit: 463; CHECK-NEXT: ret void 464; 465entry: 466 br label %loop_begin 467 468loop_begin: 469 call void @x() 470 br i1 %cond, label %loop_a, label %loop_b 471 472loop_a: 473 %v1 = load i1, ptr %ptr 474 br i1 %v1, label %loop_a_a, label %loop_a_b 475 476loop_a_a: 477 call void @a() 478 br label %loop_latch 479 480loop_a_b: 481 call void @a() 482 br label %loop_latch 483 484loop_b: 485 %v2 = load i1, ptr %ptr 486 br i1 %v2, label %loop_b_a, label %loop_b_b 487 488loop_b_a: 489 call void @b() 490 br label %loop_latch 491 492loop_b_b: 493 call void @b() 494 br label %loop_latch 495 496loop_latch: 497 call void @x() 498 call void @x() 499 %v = load i1, ptr %ptr 500 br i1 %v, label %loop_begin, label %loop_exit 501 502loop_exit: 503 ret void 504} 505 506define void @test_unswitch_large_exit(ptr %ptr, i1 %cond) { 507; CHECK-LABEL: @test_unswitch_large_exit( 508; CHECK-NEXT: entry: 509; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND:%.*]] 510; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 511; CHECK: entry.split.us: 512; CHECK-NEXT: br label [[LOOP_BEGIN_US:%.*]] 513; CHECK: loop_begin.us: 514; CHECK-NEXT: call void @x() 515; CHECK-NEXT: br label [[LOOP_A_US:%.*]] 516; CHECK: loop_a.us: 517; CHECK-NEXT: call void @a() 518; CHECK-NEXT: br label [[LOOP_LATCH_US:%.*]] 519; CHECK: loop_latch.us: 520; CHECK-NEXT: [[V_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1 521; CHECK-NEXT: br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]] 522; CHECK: loop_exit.split.us: 523; CHECK-NEXT: br label [[LOOP_EXIT:%.*]] 524; CHECK: entry.split: 525; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] 526; CHECK: loop_begin: 527; CHECK-NEXT: call void @x() 528; CHECK-NEXT: br label [[LOOP_B:%.*]] 529; CHECK: loop_b: 530; CHECK-NEXT: call void @b() 531; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] 532; CHECK: loop_latch: 533; CHECK-NEXT: [[V:%.*]] = load i1, ptr [[PTR]], align 1 534; CHECK-NEXT: br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]] 535; CHECK: loop_exit.split: 536; CHECK-NEXT: br label [[LOOP_EXIT]] 537; CHECK: loop_exit: 538; CHECK-NEXT: call void @x() 539; CHECK-NEXT: call void @x() 540; CHECK-NEXT: call void @x() 541; CHECK-NEXT: call void @x() 542; CHECK-NEXT: ret void 543; 544entry: 545 br label %loop_begin 546 547loop_begin: 548 call void @x() 549 br i1 %cond, label %loop_a, label %loop_b 550 551loop_a: 552 call void @a() 553 br label %loop_latch 554 555loop_b: 556 call void @b() 557 br label %loop_latch 558 559loop_latch: 560 %v = load i1, ptr %ptr 561 br i1 %v, label %loop_begin, label %loop_exit 562 563loop_exit: 564 call void @x() 565 call void @x() 566 call void @x() 567 call void @x() 568 ret void 569} 570 571define void @test_unswitch_dedicated_exiting(ptr %ptr, i1 %cond) { 572; CHECK-LABEL: @test_unswitch_dedicated_exiting( 573; CHECK-NEXT: entry: 574; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND:%.*]] 575; CHECK-NEXT: br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] 576; CHECK: entry.split.us: 577; CHECK-NEXT: br label [[LOOP_BEGIN_US:%.*]] 578; CHECK: loop_begin.us: 579; CHECK-NEXT: call void @x() 580; CHECK-NEXT: br label [[LOOP_A_US:%.*]] 581; CHECK: loop_a.us: 582; CHECK-NEXT: call void @a() 583; CHECK-NEXT: br label [[LOOP_LATCH_US:%.*]] 584; CHECK: loop_latch.us: 585; CHECK-NEXT: [[V_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1 586; CHECK-NEXT: br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]] 587; CHECK: loop_exit.split.us: 588; CHECK-NEXT: br label [[LOOP_EXIT:%.*]] 589; CHECK: entry.split: 590; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] 591; CHECK: loop_begin: 592; CHECK-NEXT: call void @x() 593; CHECK-NEXT: br label [[LOOP_B_EXIT:%.*]] 594; CHECK: loop_b_exit: 595; CHECK-NEXT: call void @b() 596; CHECK-NEXT: call void @b() 597; CHECK-NEXT: call void @b() 598; CHECK-NEXT: call void @b() 599; CHECK-NEXT: ret void 600; CHECK: loop_exit: 601; CHECK-NEXT: ret void 602; 603entry: 604 br label %loop_begin 605 606loop_begin: 607 call void @x() 608 br i1 %cond, label %loop_a, label %loop_b_exit 609 610loop_a: 611 call void @a() 612 br label %loop_latch 613 614loop_b_exit: 615 call void @b() 616 call void @b() 617 call void @b() 618 call void @b() 619 ret void 620 621loop_latch: 622 %v = load i1, ptr %ptr 623 br i1 %v, label %loop_begin, label %loop_exit 624 625loop_exit: 626 ret void 627} 628 629define void @test_unswitch_dedicated_exiting_minsize(ptr %ptr, i1 %cond) #0 { 630; CHECK-LABEL: @test_unswitch_dedicated_exiting_minsize( 631; CHECK-NEXT: entry: 632; CHECK-NEXT: br label [[LOOP_BEGIN:%.*]] 633; CHECK: loop_begin: 634; CHECK-NEXT: call void @x() 635; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B_EXIT:%.*]] 636; CHECK: loop_a: 637; CHECK-NEXT: call void @a() 638; CHECK-NEXT: br label [[LOOP_LATCH:%.*]] 639; CHECK: loop_b_exit: 640; CHECK-NEXT: call void @b() 641; CHECK-NEXT: call void @b() 642; CHECK-NEXT: call void @b() 643; CHECK-NEXT: call void @b() 644; CHECK-NEXT: ret void 645; CHECK: loop_latch: 646; CHECK-NEXT: [[V:%.*]] = load i1, ptr [[PTR:%.*]], align 1 647; CHECK-NEXT: br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]] 648; CHECK: loop_exit: 649; CHECK-NEXT: ret void 650; 651entry: 652 br label %loop_begin 653 654loop_begin: 655 call void @x() 656 br i1 %cond, label %loop_a, label %loop_b_exit 657 658loop_a: 659 call void @a() 660 br label %loop_latch 661 662loop_b_exit: 663 call void @b() 664 call void @b() 665 call void @b() 666 call void @b() 667 ret void 668 669loop_latch: 670 %v = load i1, ptr %ptr 671 br i1 %v, label %loop_begin, label %loop_exit 672 673loop_exit: 674 ret void 675} 676 677attributes #0 = { minsize optsize } 678