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