1; RUN: llc -mtriple=i686-linux -pre-RA-sched=source < %s | FileCheck %s 2 3declare void @error(i32 %i, i32 %a, i32 %b) 4 5define i32 @test_ifchains(i32 %i, i32* %a, i32 %b) { 6; Test a chain of ifs, where the block guarded by the if is error handling code 7; that is not expected to run. 8; CHECK-LABEL: test_ifchains: 9; CHECK: %entry 10; CHECK-NOT: .p2align 11; CHECK: %else1 12; CHECK-NOT: .p2align 13; CHECK: %else2 14; CHECK-NOT: .p2align 15; CHECK: %else3 16; CHECK-NOT: .p2align 17; CHECK: %else4 18; CHECK-NOT: .p2align 19; CHECK: %exit 20; CHECK: %then1 21; CHECK: %then2 22; CHECK: %then3 23; CHECK: %then4 24; CHECK: %then5 25 26entry: 27 %gep1 = getelementptr i32, i32* %a, i32 1 28 %val1 = load i32, i32* %gep1 29 %cond1 = icmp ugt i32 %val1, 1 30 br i1 %cond1, label %then1, label %else1, !prof !0 31 32then1: 33 call void @error(i32 %i, i32 1, i32 %b) 34 br label %else1 35 36else1: 37 %gep2 = getelementptr i32, i32* %a, i32 2 38 %val2 = load i32, i32* %gep2 39 %cond2 = icmp ugt i32 %val2, 2 40 br i1 %cond2, label %then2, label %else2, !prof !0 41 42then2: 43 call void @error(i32 %i, i32 1, i32 %b) 44 br label %else2 45 46else2: 47 %gep3 = getelementptr i32, i32* %a, i32 3 48 %val3 = load i32, i32* %gep3 49 %cond3 = icmp ugt i32 %val3, 3 50 br i1 %cond3, label %then3, label %else3, !prof !0 51 52then3: 53 call void @error(i32 %i, i32 1, i32 %b) 54 br label %else3 55 56else3: 57 %gep4 = getelementptr i32, i32* %a, i32 4 58 %val4 = load i32, i32* %gep4 59 %cond4 = icmp ugt i32 %val4, 4 60 br i1 %cond4, label %then4, label %else4, !prof !0 61 62then4: 63 call void @error(i32 %i, i32 1, i32 %b) 64 br label %else4 65 66else4: 67 %gep5 = getelementptr i32, i32* %a, i32 3 68 %val5 = load i32, i32* %gep5 69 %cond5 = icmp ugt i32 %val5, 3 70 br i1 %cond5, label %then5, label %exit, !prof !0 71 72then5: 73 call void @error(i32 %i, i32 1, i32 %b) 74 br label %exit 75 76exit: 77 ret i32 %b 78} 79 80define i32 @test_loop_cold_blocks(i32 %i, i32* %a) { 81; Check that we sink cold loop blocks after the hot loop body. 82; CHECK-LABEL: test_loop_cold_blocks: 83; CHECK: %entry 84; CHECK-NOT: .p2align 85; CHECK: %unlikely1 86; CHECK-NOT: .p2align 87; CHECK: %unlikely2 88; CHECK: .p2align 89; CHECK: %body1 90; CHECK: %body2 91; CHECK: %body3 92; CHECK: %exit 93 94entry: 95 br label %body1 96 97body1: 98 %iv = phi i32 [ 0, %entry ], [ %next, %body3 ] 99 %base = phi i32 [ 0, %entry ], [ %sum, %body3 ] 100 %unlikelycond1 = icmp slt i32 %base, 42 101 br i1 %unlikelycond1, label %unlikely1, label %body2, !prof !0 102 103unlikely1: 104 call void @error(i32 %i, i32 1, i32 %base) 105 br label %body2 106 107body2: 108 %unlikelycond2 = icmp sgt i32 %base, 21 109 br i1 %unlikelycond2, label %unlikely2, label %body3, !prof !0 110 111unlikely2: 112 call void @error(i32 %i, i32 2, i32 %base) 113 br label %body3 114 115body3: 116 %arrayidx = getelementptr inbounds i32, i32* %a, i32 %iv 117 %0 = load i32, i32* %arrayidx 118 %sum = add nsw i32 %0, %base 119 %next = add i32 %iv, 1 120 %exitcond = icmp eq i32 %next, %i 121 br i1 %exitcond, label %exit, label %body1 122 123exit: 124 ret i32 %sum 125} 126 127!0 = !{!"branch_weights", i32 4, i32 64} 128 129define i32 @test_loop_early_exits(i32 %i, i32* %a) { 130; Check that we sink early exit blocks out of loop bodies. 131; CHECK-LABEL: test_loop_early_exits: 132; CHECK: %entry 133; CHECK: %body1 134; CHECK: %body2 135; CHECK: %body3 136; CHECK: %body4 137; CHECK: %exit 138; CHECK: %bail1 139; CHECK: %bail2 140; CHECK: %bail3 141 142entry: 143 br label %body1 144 145body1: 146 %iv = phi i32 [ 0, %entry ], [ %next, %body4 ] 147 %base = phi i32 [ 0, %entry ], [ %sum, %body4 ] 148 %bailcond1 = icmp eq i32 %base, 42 149 br i1 %bailcond1, label %bail1, label %body2 150 151bail1: 152 ret i32 -1 153 154body2: 155 %bailcond2 = icmp eq i32 %base, 43 156 br i1 %bailcond2, label %bail2, label %body3 157 158bail2: 159 ret i32 -2 160 161body3: 162 %bailcond3 = icmp eq i32 %base, 44 163 br i1 %bailcond3, label %bail3, label %body4 164 165bail3: 166 ret i32 -3 167 168body4: 169 %arrayidx = getelementptr inbounds i32, i32* %a, i32 %iv 170 %0 = load i32, i32* %arrayidx 171 %sum = add nsw i32 %0, %base 172 %next = add i32 %iv, 1 173 %exitcond = icmp eq i32 %next, %i 174 br i1 %exitcond, label %exit, label %body1 175 176exit: 177 ret i32 %sum 178} 179 180; Tail duplication during layout can entirely remove body0 by duplicating it 181; into the entry block and into body1. This is a good thing but it isn't what 182; this test is looking for. So to make the blocks longer so they don't get 183; duplicated, we add some calls to dummy. 184declare void @dummy() 185 186define i32 @test_loop_rotate(i32 %i, i32* %a) { 187; Check that we rotate conditional exits from the loop to the bottom of the 188; loop, eliminating unconditional branches to the top. 189; CHECK-LABEL: test_loop_rotate: 190; CHECK: %entry 191; CHECK: %body1 192; CHECK: %body0 193; CHECK: %exit 194 195entry: 196 br label %body0 197 198body0: 199 %iv = phi i32 [ 0, %entry ], [ %next, %body1 ] 200 %base = phi i32 [ 0, %entry ], [ %sum, %body1 ] 201 %next = add i32 %iv, 1 202 %exitcond = icmp eq i32 %next, %i 203 call void @dummy() 204 call void @dummy() 205 br i1 %exitcond, label %exit, label %body1 206 207body1: 208 %arrayidx = getelementptr inbounds i32, i32* %a, i32 %iv 209 %0 = load i32, i32* %arrayidx 210 %sum = add nsw i32 %0, %base 211 %bailcond1 = icmp eq i32 %sum, 42 212 br label %body0 213 214exit: 215 ret i32 %base 216} 217 218define i32 @test_no_loop_rotate(i32 %i, i32* %a) { 219; Check that we don't try to rotate a loop which is already laid out with 220; fallthrough opportunities into the top and out of the bottom. 221; CHECK-LABEL: test_no_loop_rotate: 222; CHECK: %entry 223; CHECK: %body0 224; CHECK: %body1 225; CHECK: %exit 226 227entry: 228 br label %body0 229 230body0: 231 %iv = phi i32 [ 0, %entry ], [ %next, %body1 ] 232 %base = phi i32 [ 0, %entry ], [ %sum, %body1 ] 233 %arrayidx = getelementptr inbounds i32, i32* %a, i32 %iv 234 %0 = load i32, i32* %arrayidx 235 %sum = add nsw i32 %0, %base 236 %bailcond1 = icmp eq i32 %sum, 42 237 br i1 %bailcond1, label %exit, label %body1 238 239body1: 240 %next = add i32 %iv, 1 241 %exitcond = icmp eq i32 %next, %i 242 br i1 %exitcond, label %exit, label %body0 243 244exit: 245 ret i32 %base 246} 247 248define i32 @test_loop_align(i32 %i, i32* %a) { 249; Check that we provide basic loop body alignment with the block placement 250; pass. 251; CHECK-LABEL: test_loop_align: 252; CHECK: %entry 253; CHECK: .p2align [[ALIGN:[0-9]+]], 254; CHECK-NEXT: %body 255; CHECK: %exit 256 257entry: 258 br label %body 259 260body: 261 %iv = phi i32 [ 0, %entry ], [ %next, %body ] 262 %base = phi i32 [ 0, %entry ], [ %sum, %body ] 263 %arrayidx = getelementptr inbounds i32, i32* %a, i32 %iv 264 %0 = load i32, i32* %arrayidx 265 %sum = add nsw i32 %0, %base 266 %next = add i32 %iv, 1 267 %exitcond = icmp eq i32 %next, %i 268 br i1 %exitcond, label %exit, label %body 269 270exit: 271 ret i32 %sum 272} 273 274define i32 @test_nested_loop_align(i32 %i, i32* %a, i32* %b) { 275; Check that we provide nested loop body alignment. 276; CHECK-LABEL: test_nested_loop_align: 277; CHECK: %entry 278; CHECK: .p2align [[ALIGN]], 279; CHECK-NEXT: %loop.body.1 280; CHECK: .p2align [[ALIGN]], 281; CHECK-NEXT: %inner.loop.body 282; CHECK-NOT: .p2align 283; CHECK: %exit 284 285entry: 286 br label %loop.body.1 287 288loop.body.1: 289 %iv = phi i32 [ 0, %entry ], [ %next, %loop.body.2 ] 290 %arrayidx = getelementptr inbounds i32, i32* %a, i32 %iv 291 %bidx = load i32, i32* %arrayidx 292 br label %inner.loop.body 293 294inner.loop.body: 295 %inner.iv = phi i32 [ 0, %loop.body.1 ], [ %inner.next, %inner.loop.body ] 296 %base = phi i32 [ 0, %loop.body.1 ], [ %sum, %inner.loop.body ] 297 %scaled_idx = mul i32 %bidx, %iv 298 %inner.arrayidx = getelementptr inbounds i32, i32* %b, i32 %scaled_idx 299 %0 = load i32, i32* %inner.arrayidx 300 %sum = add nsw i32 %0, %base 301 %inner.next = add i32 %iv, 1 302 %inner.exitcond = icmp eq i32 %inner.next, %i 303 br i1 %inner.exitcond, label %loop.body.2, label %inner.loop.body 304 305loop.body.2: 306 %next = add i32 %iv, 1 307 %exitcond = icmp eq i32 %next, %i 308 br i1 %exitcond, label %exit, label %loop.body.1 309 310exit: 311 ret i32 %sum 312} 313 314define void @unnatural_cfg1() { 315; Test that we can handle a loop with an inner unnatural loop at the end of 316; a function. This is a gross CFG reduced out of the single source GCC. 317; CHECK: unnatural_cfg1 318; CHECK: %entry 319; CHECK: %loop.body1 320; CHECK: %loop.body2 321; CHECK: %loop.body3 322 323entry: 324 br label %loop.header 325 326loop.header: 327 br label %loop.body1 328 329loop.body1: 330 br i1 undef, label %loop.body3, label %loop.body2 331 332loop.body2: 333 %ptr = load i32*, i32** undef, align 4 334 br label %loop.body3 335 336loop.body3: 337 %myptr = phi i32* [ %ptr2, %loop.body5 ], [ %ptr, %loop.body2 ], [ undef, %loop.body1 ] 338 %bcmyptr = bitcast i32* %myptr to i32* 339 %val = load i32, i32* %bcmyptr, align 4 340 %comp = icmp eq i32 %val, 48 341 br i1 %comp, label %loop.body4, label %loop.body5 342 343loop.body4: 344 br i1 undef, label %loop.header, label %loop.body5 345 346loop.body5: 347 %ptr2 = load i32*, i32** undef, align 4 348 br label %loop.body3 349} 350 351define void @unnatural_cfg2() { 352; Test that we can handle a loop with a nested natural loop *and* an unnatural 353; loop. This was reduced from a crash on block placement when run over 354; single-source GCC. 355; CHECK: unnatural_cfg2 356; CHECK: %entry 357; CHECK: %loop.body1 358; CHECK: %loop.body2 359; CHECK: %loop.body3 360; CHECK: %loop.inner1.begin 361; The end block is folded with %loop.body3... 362; CHECK-NOT: %loop.inner1.end 363; CHECK: %loop.body4 364; CHECK: %loop.inner2.begin 365; The loop.inner2.end block is folded 366; CHECK: %loop.header 367; CHECK: %bail 368 369entry: 370 br label %loop.header 371 372loop.header: 373 %comp0 = icmp eq i32* undef, null 374 br i1 %comp0, label %bail, label %loop.body1 375 376loop.body1: 377 %val0 = load i32*, i32** undef, align 4 378 br i1 undef, label %loop.body2, label %loop.inner1.begin 379 380loop.body2: 381 br i1 undef, label %loop.body4, label %loop.body3 382 383loop.body3: 384 %ptr1 = getelementptr inbounds i32, i32* %val0, i32 0 385 %castptr1 = bitcast i32* %ptr1 to i32** 386 %val1 = load i32*, i32** %castptr1, align 4 387 br label %loop.inner1.begin 388 389loop.inner1.begin: 390 %valphi = phi i32* [ %val2, %loop.inner1.end ], [ %val1, %loop.body3 ], [ %val0, %loop.body1 ] 391 %castval = bitcast i32* %valphi to i32* 392 %comp1 = icmp eq i32 undef, 48 393 br i1 %comp1, label %loop.inner1.end, label %loop.body4 394 395loop.inner1.end: 396 %ptr2 = getelementptr inbounds i32, i32* %valphi, i32 0 397 %castptr2 = bitcast i32* %ptr2 to i32** 398 %val2 = load i32*, i32** %castptr2, align 4 399 br label %loop.inner1.begin 400 401loop.body4.dead: 402 br label %loop.body4 403 404loop.body4: 405 %comp2 = icmp ult i32 undef, 3 406 br i1 %comp2, label %loop.inner2.begin, label %loop.end 407 408loop.inner2.begin: 409 br i1 false, label %loop.end, label %loop.inner2.end 410 411loop.inner2.end: 412 %comp3 = icmp eq i32 undef, 1769472 413 br i1 %comp3, label %loop.end, label %loop.inner2.begin 414 415loop.end: 416 br label %loop.header 417 418bail: 419 unreachable 420} 421 422define i32 @problematic_switch() { 423; This function's CFG caused overlow in the machine branch probability 424; calculation, triggering asserts. Make sure we don't crash on it. 425; CHECK: problematic_switch 426 427entry: 428 switch i32 undef, label %exit [ 429 i32 879, label %bogus 430 i32 877, label %step 431 i32 876, label %step 432 i32 875, label %step 433 i32 874, label %step 434 i32 873, label %step 435 i32 872, label %step 436 i32 868, label %step 437 i32 867, label %step 438 i32 866, label %step 439 i32 861, label %step 440 i32 860, label %step 441 i32 856, label %step 442 i32 855, label %step 443 i32 854, label %step 444 i32 831, label %step 445 i32 830, label %step 446 i32 829, label %step 447 i32 828, label %step 448 i32 815, label %step 449 i32 814, label %step 450 i32 811, label %step 451 i32 806, label %step 452 i32 805, label %step 453 i32 804, label %step 454 i32 803, label %step 455 i32 802, label %step 456 i32 801, label %step 457 i32 800, label %step 458 i32 799, label %step 459 i32 798, label %step 460 i32 797, label %step 461 i32 796, label %step 462 i32 795, label %step 463 ] 464bogus: 465 unreachable 466step: 467 br label %exit 468exit: 469 %merge = phi i32 [ 3, %step ], [ 6, %entry ] 470 ret i32 %merge 471} 472 473define void @fpcmp_unanalyzable_branch(i1 %cond) { 474; This function's CFG contains an once-unanalyzable branch (une on floating 475; points). As now it becomes analyzable, we should get best layout in which each 476; edge in 'entry' -> 'entry.if.then_crit_edge' -> 'if.then' -> 'if.end' is 477; fall-through. 478; CHECK-LABEL: fpcmp_unanalyzable_branch: 479; CHECK: # BB#0: # %entry 480; CHECK: # BB#1: # %entry.if.then_crit_edge 481; CHECK: .LBB10_5: # %if.then 482; CHECK: .LBB10_6: # %if.end 483; CHECK: # BB#3: # %exit 484; CHECK: jne .LBB10_4 485; CHECK-NEXT: jnp .LBB10_6 486; CHECK: jmp .LBB10_5 487 488entry: 489; Note that this branch must be strongly biased toward 490; 'entry.if.then_crit_edge' to ensure that we would try to form a chain for 491; 'entry' -> 'entry.if.then_crit_edge' -> 'if.then' -> 'if.end'. 492 br i1 %cond, label %entry.if.then_crit_edge, label %lor.lhs.false, !prof !1 493 494entry.if.then_crit_edge: 495 %.pre14 = load i8, i8* undef, align 1 496 br label %if.then 497 498lor.lhs.false: 499 br i1 undef, label %if.end, label %exit 500 501exit: 502 %cmp.i = fcmp une double 0.000000e+00, undef 503 br i1 %cmp.i, label %if.then, label %if.end, !prof !3 504 505if.then: 506 %0 = phi i8 [ %.pre14, %entry.if.then_crit_edge ], [ undef, %exit ] 507 %1 = and i8 %0, 1 508 store i8 %1, i8* undef, align 4 509 br label %if.end 510 511if.end: 512 ret void 513} 514 515!1 = !{!"branch_weights", i32 1000, i32 1} 516!3 = !{!"branch_weights", i32 1, i32 1000} 517 518declare i32 @f() 519declare i32 @g() 520declare i32 @h(i32 %x) 521 522define i32 @test_global_cfg_break_profitability() { 523; Check that our metrics for the profitability of a CFG break are global rather 524; than local. A successor may be very hot, but if the current block isn't, it 525; doesn't matter. Within this test the 'then' block is slightly warmer than the 526; 'else' block, but not nearly enough to merit merging it with the exit block 527; even though the probability of 'then' branching to the 'exit' block is very 528; high. 529; CHECK: test_global_cfg_break_profitability 530; CHECK: calll {{_?}}f 531; CHECK: calll {{_?}}g 532; CHECK: calll {{_?}}h 533; CHECK: ret 534 535entry: 536 br i1 undef, label %then, label %else, !prof !2 537 538then: 539 %then.result = call i32 @f() 540 br label %exit 541 542else: 543 %else.result = call i32 @g() 544 br label %exit 545 546exit: 547 %result = phi i32 [ %then.result, %then ], [ %else.result, %else ] 548 %result2 = call i32 @h(i32 %result) 549 ret i32 %result 550} 551 552!2 = !{!"branch_weights", i32 3, i32 1} 553 554declare i32 @__gxx_personality_v0(...) 555 556define void @test_eh_lpad_successor() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 557; Some times the landing pad ends up as the first successor of an invoke block. 558; When this happens, a strange result used to fall out of updateTerminators: we 559; didn't correctly locate the fallthrough successor, assuming blindly that the 560; first one was the fallthrough successor. As a result, we would add an 561; erroneous jump to the landing pad thinking *that* was the default successor. 562; CHECK: test_eh_lpad_successor 563; CHECK: %entry 564; CHECK-NOT: jmp 565; CHECK: %loop 566 567entry: 568 invoke i32 @f() to label %preheader unwind label %lpad 569 570preheader: 571 br label %loop 572 573lpad: 574 %lpad.val = landingpad { i8*, i32 } 575 cleanup 576 resume { i8*, i32 } %lpad.val 577 578loop: 579 br label %loop 580} 581 582declare void @fake_throw() noreturn 583 584define void @test_eh_throw() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 585; For blocks containing a 'throw' (or similar functionality), we have 586; a no-return invoke. In this case, only EH successors will exist, and 587; fallthrough simply won't occur. Make sure we don't crash trying to update 588; terminators for such constructs. 589; 590; CHECK: test_eh_throw 591; CHECK: %entry 592; CHECK: %cleanup 593 594entry: 595 invoke void @fake_throw() to label %continue unwind label %cleanup 596 597continue: 598 unreachable 599 600cleanup: 601 %0 = landingpad { i8*, i32 } 602 cleanup 603 unreachable 604} 605 606define void @test_unnatural_cfg_backwards_inner_loop() { 607; Test that when we encounter an unnatural CFG structure after having formed 608; a chain for an inner loop which happened to be laid out backwards we don't 609; attempt to merge onto the wrong end of the inner loop just because we find it 610; first. This was reduced from a crasher in GCC's single source. 611; 612; CHECK: test_unnatural_cfg_backwards_inner_loop 613; CHECK: %entry 614; CHECK: %loop2b 615; CHECK: %loop1 616 617entry: 618 br i1 undef, label %loop2a, label %body 619 620body: 621 br label %loop2a 622 623loop1: 624 %next.load = load i32*, i32** undef 625 br i1 %comp.a, label %loop2a, label %loop2b 626 627loop2a: 628 %var = phi i32* [ null, %entry ], [ null, %body ], [ %next.phi, %loop1 ] 629 %next.var = phi i32* [ null, %entry ], [ undef, %body ], [ %next.load, %loop1 ] 630 %comp.a = icmp eq i32* %var, null 631 br label %loop3 632 633loop2b: 634 %gep = getelementptr inbounds i32, i32* %var.phi, i32 0 635 %next.ptr = bitcast i32* %gep to i32** 636 store i32* %next.phi, i32** %next.ptr 637 br label %loop3 638 639loop3: 640 %var.phi = phi i32* [ %next.phi, %loop2b ], [ %var, %loop2a ] 641 %next.phi = phi i32* [ %next.load, %loop2b ], [ %next.var, %loop2a ] 642 br label %loop1 643} 644 645define void @unanalyzable_branch_to_loop_header() { 646; Ensure that we can handle unanalyzable branches into loop headers. We 647; pre-form chains for unanalyzable branches, and will find the tail end of that 648; at the start of the loop. This function uses floating point comparison 649; fallthrough because that happens to always produce unanalyzable branches on 650; x86. 651; 652; CHECK: unanalyzable_branch_to_loop_header 653; CHECK: %entry 654; CHECK: %loop 655; CHECK: %exit 656 657entry: 658 %cmp = fcmp une double 0.000000e+00, undef 659 br i1 %cmp, label %loop, label %exit 660 661loop: 662 %cond = icmp eq i8 undef, 42 663 br i1 %cond, label %exit, label %loop 664 665exit: 666 ret void 667} 668 669define void @unanalyzable_branch_to_best_succ(i1 %cond) { 670; Ensure that we can handle unanalyzable branches where the destination block 671; gets selected as the optimal successor to merge. 672; 673; This branch is now analyzable and hence the destination block becomes the 674; hotter one. The right order is entry->bar->exit->foo. 675; 676; CHECK: unanalyzable_branch_to_best_succ 677; CHECK: %entry 678; CHECK: %bar 679; CHECK: %exit 680; CHECK: %foo 681 682entry: 683 ; Bias this branch toward bar to ensure we form that chain. 684 br i1 %cond, label %bar, label %foo, !prof !1 685 686foo: 687 %cmp = fcmp une double 0.000000e+00, undef 688 br i1 %cmp, label %bar, label %exit 689 690bar: 691 call i32 @f() 692 br label %exit 693 694exit: 695 ret void 696} 697 698define void @unanalyzable_branch_to_free_block(float %x) { 699; Ensure that we can handle unanalyzable branches where the destination block 700; gets selected as the best free block in the CFG. 701; 702; CHECK: unanalyzable_branch_to_free_block 703; CHECK: %entry 704; CHECK: %a 705; CHECK: %b 706; CHECK: %c 707; CHECK: %exit 708 709entry: 710 br i1 undef, label %a, label %b 711 712a: 713 call i32 @f() 714 br label %c 715 716b: 717 %cmp = fcmp une float %x, undef 718 br i1 %cmp, label %c, label %exit 719 720c: 721 call i32 @g() 722 br label %exit 723 724exit: 725 ret void 726} 727 728define void @many_unanalyzable_branches() { 729; Ensure that we don't crash as we're building up many unanalyzable branches, 730; blocks, and loops. 731; 732; CHECK: many_unanalyzable_branches 733; CHECK: %entry 734; CHECK: %exit 735 736entry: 737 br label %0 738 739 %val0 = load volatile float, float* undef 740 %cmp0 = fcmp une float %val0, undef 741 br i1 %cmp0, label %1, label %0 742 %val1 = load volatile float, float* undef 743 %cmp1 = fcmp une float %val1, undef 744 br i1 %cmp1, label %2, label %1 745 %val2 = load volatile float, float* undef 746 %cmp2 = fcmp une float %val2, undef 747 br i1 %cmp2, label %3, label %2 748 %val3 = load volatile float, float* undef 749 %cmp3 = fcmp une float %val3, undef 750 br i1 %cmp3, label %4, label %3 751 %val4 = load volatile float, float* undef 752 %cmp4 = fcmp une float %val4, undef 753 br i1 %cmp4, label %5, label %4 754 %val5 = load volatile float, float* undef 755 %cmp5 = fcmp une float %val5, undef 756 br i1 %cmp5, label %6, label %5 757 %val6 = load volatile float, float* undef 758 %cmp6 = fcmp une float %val6, undef 759 br i1 %cmp6, label %7, label %6 760 %val7 = load volatile float, float* undef 761 %cmp7 = fcmp une float %val7, undef 762 br i1 %cmp7, label %8, label %7 763 %val8 = load volatile float, float* undef 764 %cmp8 = fcmp une float %val8, undef 765 br i1 %cmp8, label %9, label %8 766 %val9 = load volatile float, float* undef 767 %cmp9 = fcmp une float %val9, undef 768 br i1 %cmp9, label %10, label %9 769 %val10 = load volatile float, float* undef 770 %cmp10 = fcmp une float %val10, undef 771 br i1 %cmp10, label %11, label %10 772 %val11 = load volatile float, float* undef 773 %cmp11 = fcmp une float %val11, undef 774 br i1 %cmp11, label %12, label %11 775 %val12 = load volatile float, float* undef 776 %cmp12 = fcmp une float %val12, undef 777 br i1 %cmp12, label %13, label %12 778 %val13 = load volatile float, float* undef 779 %cmp13 = fcmp une float %val13, undef 780 br i1 %cmp13, label %14, label %13 781 %val14 = load volatile float, float* undef 782 %cmp14 = fcmp une float %val14, undef 783 br i1 %cmp14, label %15, label %14 784 %val15 = load volatile float, float* undef 785 %cmp15 = fcmp une float %val15, undef 786 br i1 %cmp15, label %16, label %15 787 %val16 = load volatile float, float* undef 788 %cmp16 = fcmp une float %val16, undef 789 br i1 %cmp16, label %17, label %16 790 %val17 = load volatile float, float* undef 791 %cmp17 = fcmp une float %val17, undef 792 br i1 %cmp17, label %18, label %17 793 %val18 = load volatile float, float* undef 794 %cmp18 = fcmp une float %val18, undef 795 br i1 %cmp18, label %19, label %18 796 %val19 = load volatile float, float* undef 797 %cmp19 = fcmp une float %val19, undef 798 br i1 %cmp19, label %20, label %19 799 %val20 = load volatile float, float* undef 800 %cmp20 = fcmp une float %val20, undef 801 br i1 %cmp20, label %21, label %20 802 %val21 = load volatile float, float* undef 803 %cmp21 = fcmp une float %val21, undef 804 br i1 %cmp21, label %22, label %21 805 %val22 = load volatile float, float* undef 806 %cmp22 = fcmp une float %val22, undef 807 br i1 %cmp22, label %23, label %22 808 %val23 = load volatile float, float* undef 809 %cmp23 = fcmp une float %val23, undef 810 br i1 %cmp23, label %24, label %23 811 %val24 = load volatile float, float* undef 812 %cmp24 = fcmp une float %val24, undef 813 br i1 %cmp24, label %25, label %24 814 %val25 = load volatile float, float* undef 815 %cmp25 = fcmp une float %val25, undef 816 br i1 %cmp25, label %26, label %25 817 %val26 = load volatile float, float* undef 818 %cmp26 = fcmp une float %val26, undef 819 br i1 %cmp26, label %27, label %26 820 %val27 = load volatile float, float* undef 821 %cmp27 = fcmp une float %val27, undef 822 br i1 %cmp27, label %28, label %27 823 %val28 = load volatile float, float* undef 824 %cmp28 = fcmp une float %val28, undef 825 br i1 %cmp28, label %29, label %28 826 %val29 = load volatile float, float* undef 827 %cmp29 = fcmp une float %val29, undef 828 br i1 %cmp29, label %30, label %29 829 %val30 = load volatile float, float* undef 830 %cmp30 = fcmp une float %val30, undef 831 br i1 %cmp30, label %31, label %30 832 %val31 = load volatile float, float* undef 833 %cmp31 = fcmp une float %val31, undef 834 br i1 %cmp31, label %32, label %31 835 %val32 = load volatile float, float* undef 836 %cmp32 = fcmp une float %val32, undef 837 br i1 %cmp32, label %33, label %32 838 %val33 = load volatile float, float* undef 839 %cmp33 = fcmp une float %val33, undef 840 br i1 %cmp33, label %34, label %33 841 %val34 = load volatile float, float* undef 842 %cmp34 = fcmp une float %val34, undef 843 br i1 %cmp34, label %35, label %34 844 %val35 = load volatile float, float* undef 845 %cmp35 = fcmp une float %val35, undef 846 br i1 %cmp35, label %36, label %35 847 %val36 = load volatile float, float* undef 848 %cmp36 = fcmp une float %val36, undef 849 br i1 %cmp36, label %37, label %36 850 %val37 = load volatile float, float* undef 851 %cmp37 = fcmp une float %val37, undef 852 br i1 %cmp37, label %38, label %37 853 %val38 = load volatile float, float* undef 854 %cmp38 = fcmp une float %val38, undef 855 br i1 %cmp38, label %39, label %38 856 %val39 = load volatile float, float* undef 857 %cmp39 = fcmp une float %val39, undef 858 br i1 %cmp39, label %40, label %39 859 %val40 = load volatile float, float* undef 860 %cmp40 = fcmp une float %val40, undef 861 br i1 %cmp40, label %41, label %40 862 %val41 = load volatile float, float* undef 863 %cmp41 = fcmp une float %val41, undef 864 br i1 %cmp41, label %42, label %41 865 %val42 = load volatile float, float* undef 866 %cmp42 = fcmp une float %val42, undef 867 br i1 %cmp42, label %43, label %42 868 %val43 = load volatile float, float* undef 869 %cmp43 = fcmp une float %val43, undef 870 br i1 %cmp43, label %44, label %43 871 %val44 = load volatile float, float* undef 872 %cmp44 = fcmp une float %val44, undef 873 br i1 %cmp44, label %45, label %44 874 %val45 = load volatile float, float* undef 875 %cmp45 = fcmp une float %val45, undef 876 br i1 %cmp45, label %46, label %45 877 %val46 = load volatile float, float* undef 878 %cmp46 = fcmp une float %val46, undef 879 br i1 %cmp46, label %47, label %46 880 %val47 = load volatile float, float* undef 881 %cmp47 = fcmp une float %val47, undef 882 br i1 %cmp47, label %48, label %47 883 %val48 = load volatile float, float* undef 884 %cmp48 = fcmp une float %val48, undef 885 br i1 %cmp48, label %49, label %48 886 %val49 = load volatile float, float* undef 887 %cmp49 = fcmp une float %val49, undef 888 br i1 %cmp49, label %50, label %49 889 %val50 = load volatile float, float* undef 890 %cmp50 = fcmp une float %val50, undef 891 br i1 %cmp50, label %51, label %50 892 %val51 = load volatile float, float* undef 893 %cmp51 = fcmp une float %val51, undef 894 br i1 %cmp51, label %52, label %51 895 %val52 = load volatile float, float* undef 896 %cmp52 = fcmp une float %val52, undef 897 br i1 %cmp52, label %53, label %52 898 %val53 = load volatile float, float* undef 899 %cmp53 = fcmp une float %val53, undef 900 br i1 %cmp53, label %54, label %53 901 %val54 = load volatile float, float* undef 902 %cmp54 = fcmp une float %val54, undef 903 br i1 %cmp54, label %55, label %54 904 %val55 = load volatile float, float* undef 905 %cmp55 = fcmp une float %val55, undef 906 br i1 %cmp55, label %56, label %55 907 %val56 = load volatile float, float* undef 908 %cmp56 = fcmp une float %val56, undef 909 br i1 %cmp56, label %57, label %56 910 %val57 = load volatile float, float* undef 911 %cmp57 = fcmp une float %val57, undef 912 br i1 %cmp57, label %58, label %57 913 %val58 = load volatile float, float* undef 914 %cmp58 = fcmp une float %val58, undef 915 br i1 %cmp58, label %59, label %58 916 %val59 = load volatile float, float* undef 917 %cmp59 = fcmp une float %val59, undef 918 br i1 %cmp59, label %60, label %59 919 %val60 = load volatile float, float* undef 920 %cmp60 = fcmp une float %val60, undef 921 br i1 %cmp60, label %61, label %60 922 %val61 = load volatile float, float* undef 923 %cmp61 = fcmp une float %val61, undef 924 br i1 %cmp61, label %62, label %61 925 %val62 = load volatile float, float* undef 926 %cmp62 = fcmp une float %val62, undef 927 br i1 %cmp62, label %63, label %62 928 %val63 = load volatile float, float* undef 929 %cmp63 = fcmp une float %val63, undef 930 br i1 %cmp63, label %64, label %63 931 %val64 = load volatile float, float* undef 932 %cmp64 = fcmp une float %val64, undef 933 br i1 %cmp64, label %65, label %64 934 935 br label %exit 936exit: 937 ret void 938} 939 940define void @benchmark_heapsort(i32 %n, double* nocapture %ra) { 941; This test case comes from the heapsort benchmark, and exemplifies several 942; important aspects to block placement in the presence of loops: 943; 1) Loop rotation needs to *ensure* that the desired exiting edge can be 944; a fallthrough. 945; 2) The exiting edge from the loop which is rotated to be laid out at the 946; bottom of the loop needs to be exiting into the nearest enclosing loop (to 947; which there is an exit). Otherwise, we force that enclosing loop into 948; strange layouts that are siginificantly less efficient, often times maing 949; it discontiguous. 950; 951; CHECK: @benchmark_heapsort 952; CHECK: %entry 953; First rotated loop top. 954; CHECK: .p2align 955; CHECK: %while.end 956; %for.cond gets completely tail-duplicated away. 957; CHECK: %if.then 958; CHECK: %if.else 959; CHECK: %if.end10 960; Second rotated loop top 961; CHECK: .p2align 962; CHECK: %if.then24 963; CHECK: %while.cond.outer 964; Third rotated loop top 965; CHECK: .p2align 966; CHECK: %while.cond 967; CHECK: %while.body 968; CHECK: %land.lhs.true 969; CHECK: %if.then19 970; CHECK: %if.end20 971; CHECK: %if.then8 972; CHECK: ret 973 974entry: 975 %shr = ashr i32 %n, 1 976 %add = add nsw i32 %shr, 1 977 %arrayidx3 = getelementptr inbounds double, double* %ra, i64 1 978 br label %for.cond 979 980for.cond: 981 %ir.0 = phi i32 [ %n, %entry ], [ %ir.1, %while.end ] 982 %l.0 = phi i32 [ %add, %entry ], [ %l.1, %while.end ] 983 %cmp = icmp sgt i32 %l.0, 1 984 br i1 %cmp, label %if.then, label %if.else 985 986if.then: 987 %dec = add nsw i32 %l.0, -1 988 %idxprom = sext i32 %dec to i64 989 %arrayidx = getelementptr inbounds double, double* %ra, i64 %idxprom 990 %0 = load double, double* %arrayidx, align 8 991 br label %if.end10 992 993if.else: 994 %idxprom1 = sext i32 %ir.0 to i64 995 %arrayidx2 = getelementptr inbounds double, double* %ra, i64 %idxprom1 996 %1 = load double, double* %arrayidx2, align 8 997 %2 = load double, double* %arrayidx3, align 8 998 store double %2, double* %arrayidx2, align 8 999 %dec6 = add nsw i32 %ir.0, -1 1000 %cmp7 = icmp eq i32 %dec6, 1 1001 br i1 %cmp7, label %if.then8, label %if.end10 1002 1003if.then8: 1004 store double %1, double* %arrayidx3, align 8 1005 ret void 1006 1007if.end10: 1008 %ir.1 = phi i32 [ %ir.0, %if.then ], [ %dec6, %if.else ] 1009 %l.1 = phi i32 [ %dec, %if.then ], [ %l.0, %if.else ] 1010 %rra.0 = phi double [ %0, %if.then ], [ %1, %if.else ] 1011 %add31 = add nsw i32 %ir.1, 1 1012 br label %while.cond.outer 1013 1014while.cond.outer: 1015 %j.0.ph.in = phi i32 [ %l.1, %if.end10 ], [ %j.1, %if.then24 ] 1016 %j.0.ph = shl i32 %j.0.ph.in, 1 1017 br label %while.cond 1018 1019while.cond: 1020 %j.0 = phi i32 [ %add31, %if.end20 ], [ %j.0.ph, %while.cond.outer ] 1021 %cmp11 = icmp sgt i32 %j.0, %ir.1 1022 br i1 %cmp11, label %while.end, label %while.body 1023 1024while.body: 1025 %cmp12 = icmp slt i32 %j.0, %ir.1 1026 br i1 %cmp12, label %land.lhs.true, label %if.end20 1027 1028land.lhs.true: 1029 %idxprom13 = sext i32 %j.0 to i64 1030 %arrayidx14 = getelementptr inbounds double, double* %ra, i64 %idxprom13 1031 %3 = load double, double* %arrayidx14, align 8 1032 %add15 = add nsw i32 %j.0, 1 1033 %idxprom16 = sext i32 %add15 to i64 1034 %arrayidx17 = getelementptr inbounds double, double* %ra, i64 %idxprom16 1035 %4 = load double, double* %arrayidx17, align 8 1036 %cmp18 = fcmp olt double %3, %4 1037 br i1 %cmp18, label %if.then19, label %if.end20 1038 1039if.then19: 1040 br label %if.end20 1041 1042if.end20: 1043 %j.1 = phi i32 [ %add15, %if.then19 ], [ %j.0, %land.lhs.true ], [ %j.0, %while.body ] 1044 %idxprom21 = sext i32 %j.1 to i64 1045 %arrayidx22 = getelementptr inbounds double, double* %ra, i64 %idxprom21 1046 %5 = load double, double* %arrayidx22, align 8 1047 %cmp23 = fcmp olt double %rra.0, %5 1048 br i1 %cmp23, label %if.then24, label %while.cond 1049 1050if.then24: 1051 %idxprom27 = sext i32 %j.0.ph.in to i64 1052 %arrayidx28 = getelementptr inbounds double, double* %ra, i64 %idxprom27 1053 store double %5, double* %arrayidx28, align 8 1054 br label %while.cond.outer 1055 1056while.end: 1057 %idxprom33 = sext i32 %j.0.ph.in to i64 1058 %arrayidx34 = getelementptr inbounds double, double* %ra, i64 %idxprom33 1059 store double %rra.0, double* %arrayidx34, align 8 1060 br label %for.cond 1061} 1062 1063declare void @cold_function() cold 1064 1065define i32 @test_cold_calls(i32* %a) { 1066; Test that edges to blocks post-dominated by cold calls are 1067; marked as not expected to be taken. They should be laid out 1068; at the bottom. 1069; CHECK-LABEL: test_cold_calls: 1070; CHECK: %entry 1071; CHECK: %else 1072; CHECK: %exit 1073; CHECK: %then 1074 1075entry: 1076 %gep1 = getelementptr i32, i32* %a, i32 1 1077 %val1 = load i32, i32* %gep1 1078 %cond1 = icmp ugt i32 %val1, 1 1079 br i1 %cond1, label %then, label %else 1080 1081then: 1082 call void @cold_function() 1083 br label %exit 1084 1085else: 1086 %gep2 = getelementptr i32, i32* %a, i32 2 1087 %val2 = load i32, i32* %gep2 1088 br label %exit 1089 1090exit: 1091 %ret = phi i32 [ %val1, %then ], [ %val2, %else ] 1092 ret i32 %ret 1093} 1094 1095; Make sure we put landingpads out of the way. 1096declare i32 @pers(...) 1097 1098declare i32 @foo(); 1099 1100declare i32 @bar(); 1101 1102define i32 @test_lp(i32 %a) personality i32 (...)* @pers { 1103; CHECK-LABEL: test_lp: 1104; CHECK: %entry 1105; CHECK: %hot 1106; CHECK: %then 1107; CHECK: %cold 1108; CHECK: %coldlp 1109; CHECK: %hotlp 1110; CHECK: %lpret 1111entry: 1112 %0 = icmp sgt i32 %a, 1 1113 br i1 %0, label %hot, label %cold, !prof !4 1114 1115hot: 1116 %1 = invoke i32 @foo() 1117 to label %then unwind label %hotlp 1118 1119cold: 1120 %2 = invoke i32 @bar() 1121 to label %then unwind label %coldlp 1122 1123then: 1124 %3 = phi i32 [ %1, %hot ], [ %2, %cold ] 1125 ret i32 %3 1126 1127hotlp: 1128 %4 = landingpad { i8*, i32 } 1129 cleanup 1130 br label %lpret 1131 1132coldlp: 1133 %5 = landingpad { i8*, i32 } 1134 cleanup 1135 br label %lpret 1136 1137lpret: 1138 %6 = phi i32 [-1, %hotlp], [-2, %coldlp] 1139 %7 = add i32 %6, 42 1140 ret i32 %7 1141} 1142 1143!4 = !{!"branch_weights", i32 65536, i32 0} 1144 1145; Make sure that ehpad are scheduled from the least probable one 1146; to the most probable one. See selectBestCandidateBlock as to why. 1147declare void @clean(); 1148 1149define void @test_flow_unwind() personality i32 (...)* @pers { 1150; CHECK-LABEL: test_flow_unwind: 1151; CHECK: %entry 1152; CHECK: %then 1153; CHECK: %exit 1154; CHECK: %innerlp 1155; CHECK: %outerlp 1156; CHECK: %outercleanup 1157entry: 1158 %0 = invoke i32 @foo() 1159 to label %then unwind label %outerlp 1160 1161then: 1162 %1 = invoke i32 @bar() 1163 to label %exit unwind label %innerlp 1164 1165exit: 1166 ret void 1167 1168innerlp: 1169 %2 = landingpad { i8*, i32 } 1170 cleanup 1171 br label %innercleanup 1172 1173outerlp: 1174 %3 = landingpad { i8*, i32 } 1175 cleanup 1176 br label %outercleanup 1177 1178outercleanup: 1179 %4 = phi { i8*, i32 } [%2, %innercleanup], [%3, %outerlp] 1180 call void @clean() 1181 resume { i8*, i32 } %4 1182 1183innercleanup: 1184 call void @clean() 1185 br label %outercleanup 1186} 1187 1188declare void @hot_function() 1189 1190define void @test_hot_branch(i32* %a) { 1191; Test that a hot branch that has a probability a little larger than 80% will 1192; break CFG constrains when doing block placement. 1193; CHECK-LABEL: test_hot_branch: 1194; CHECK: %entry 1195; CHECK: %then 1196; CHECK: %exit 1197; CHECK: %else 1198 1199entry: 1200 %gep1 = getelementptr i32, i32* %a, i32 1 1201 %val1 = load i32, i32* %gep1 1202 %cond1 = icmp ugt i32 %val1, 1 1203 br i1 %cond1, label %then, label %else, !prof !5 1204 1205then: 1206 call void @hot_function() 1207 br label %exit 1208 1209else: 1210 call void @cold_function() 1211 br label %exit 1212 1213exit: 1214 call void @hot_function() 1215 ret void 1216} 1217 1218define void @test_hot_branch_profile(i32* %a) !prof !6 { 1219; Test that a hot branch that has a probability a little larger than 50% will 1220; break CFG constrains when doing block placement when profile is available. 1221; CHECK-LABEL: test_hot_branch_profile: 1222; CHECK: %entry 1223; CHECK: %then 1224; CHECK: %exit 1225; CHECK: %else 1226 1227entry: 1228 %gep1 = getelementptr i32, i32* %a, i32 1 1229 %val1 = load i32, i32* %gep1 1230 %cond1 = icmp ugt i32 %val1, 1 1231 br i1 %cond1, label %then, label %else, !prof !7 1232 1233then: 1234 call void @hot_function() 1235 br label %exit 1236 1237else: 1238 call void @cold_function() 1239 br label %exit 1240 1241exit: 1242 call void @hot_function() 1243 ret void 1244} 1245 1246define void @test_hot_branch_triangle_profile(i32* %a) !prof !6 { 1247; Test that a hot branch that has a probability a little larger than 80% will 1248; break triangle shaped CFG constrains when doing block placement if profile 1249; is present. 1250; CHECK-LABEL: test_hot_branch_triangle_profile: 1251; CHECK: %entry 1252; CHECK: %exit 1253; CHECK: %then 1254 1255entry: 1256 %gep1 = getelementptr i32, i32* %a, i32 1 1257 %val1 = load i32, i32* %gep1 1258 %cond1 = icmp ugt i32 %val1, 1 1259 br i1 %cond1, label %exit, label %then, !prof !5 1260 1261then: 1262 call void @hot_function() 1263 br label %exit 1264 1265exit: 1266 call void @hot_function() 1267 ret void 1268} 1269 1270define void @test_hot_branch_triangle_profile_topology(i32* %a) !prof !6 { 1271; Test that a hot branch that has a probability between 50% and 66% will not 1272; break triangle shaped CFG constrains when doing block placement if profile 1273; is present. 1274; CHECK-LABEL: test_hot_branch_triangle_profile_topology: 1275; CHECK: %entry 1276; CHECK: %then 1277; CHECK: %exit 1278 1279entry: 1280 %gep1 = getelementptr i32, i32* %a, i32 1 1281 %val1 = load i32, i32* %gep1 1282 %cond1 = icmp ugt i32 %val1, 1 1283 br i1 %cond1, label %exit, label %then, !prof !7 1284 1285then: 1286 call void @hot_function() 1287 br label %exit 1288 1289exit: 1290 call void @hot_function() 1291 ret void 1292} 1293 1294declare void @a() 1295declare void @b() 1296 1297define void @test_forked_hot_diamond(i32* %a) { 1298; Test that a hot-branch with probability > 80% followed by a 50/50 branch 1299; will not place the cold predecessor if the probability for the fallthrough 1300; remains above 80% 1301; CHECK-LABEL: test_forked_hot_diamond 1302; CHECK: %entry 1303; CHECK: %then 1304; CHECK: %fork1 1305; CHECK: %else 1306; CHECK: %fork2 1307; CHECK: %exit 1308entry: 1309 %gep1 = getelementptr i32, i32* %a, i32 1 1310 %val1 = load i32, i32* %gep1 1311 %cond1 = icmp ugt i32 %val1, 1 1312 br i1 %cond1, label %then, label %else, !prof !5 1313 1314then: 1315 call void @hot_function() 1316 %gep2 = getelementptr i32, i32* %a, i32 2 1317 %val2 = load i32, i32* %gep2 1318 %cond2 = icmp ugt i32 %val2, 2 1319 br i1 %cond2, label %fork1, label %fork2, !prof !8 1320 1321else: 1322 call void @cold_function() 1323 %gep3 = getelementptr i32, i32* %a, i32 3 1324 %val3 = load i32, i32* %gep3 1325 %cond3 = icmp ugt i32 %val3, 3 1326 br i1 %cond3, label %fork1, label %fork2, !prof !8 1327 1328fork1: 1329 call void @a() 1330 br label %exit 1331 1332fork2: 1333 call void @b() 1334 br label %exit 1335 1336exit: 1337 call void @hot_function() 1338 ret void 1339} 1340 1341define void @test_forked_hot_diamond_gets_cold(i32* %a) { 1342; Test that a hot-branch with probability > 80% followed by a 50/50 branch 1343; will place the cold predecessor if the probability for the fallthrough 1344; falls below 80% 1345; The probability for both branches is 85%. For then2 vs else1 1346; this results in a compounded probability of 83%. 1347; Neither then2->fork1 nor then2->fork2 has a large enough relative 1348; probability to break the CFG. 1349; Relative probs: 1350; then2 -> fork1 vs else1 -> fork1 = 71% 1351; then2 -> fork2 vs else2 -> fork2 = 74% 1352; CHECK-LABEL: test_forked_hot_diamond_gets_cold 1353; CHECK: %entry 1354; CHECK: %then1 1355; CHECK: %then2 1356; CHECK: %else1 1357; CHECK: %fork1 1358; CHECK: %else2 1359; CHECK: %fork2 1360; CHECK: %exit 1361entry: 1362 %gep1 = getelementptr i32, i32* %a, i32 1 1363 %val1 = load i32, i32* %gep1 1364 %cond1 = icmp ugt i32 %val1, 1 1365 br i1 %cond1, label %then1, label %else1, !prof !9 1366 1367then1: 1368 call void @hot_function() 1369 %gep2 = getelementptr i32, i32* %a, i32 2 1370 %val2 = load i32, i32* %gep2 1371 %cond2 = icmp ugt i32 %val2, 2 1372 br i1 %cond2, label %then2, label %else2, !prof !9 1373 1374else1: 1375 call void @cold_function() 1376 br label %fork1 1377 1378then2: 1379 call void @hot_function() 1380 %gep3 = getelementptr i32, i32* %a, i32 3 1381 %val3 = load i32, i32* %gep2 1382 %cond3 = icmp ugt i32 %val2, 3 1383 br i1 %cond3, label %fork1, label %fork2, !prof !8 1384 1385else2: 1386 call void @cold_function() 1387 br label %fork2 1388 1389fork1: 1390 call void @a() 1391 br label %exit 1392 1393fork2: 1394 call void @b() 1395 br label %exit 1396 1397exit: 1398 call void @hot_function() 1399 ret void 1400} 1401 1402define void @test_forked_hot_diamond_stays_hot(i32* %a) { 1403; Test that a hot-branch with probability > 88.88% (1:8) followed by a 50/50 1404; branch will not place the cold predecessor as the probability for the 1405; fallthrough stays above 80% 1406; (1:8) followed by (1:1) is still (1:4) 1407; Here we use 90% probability because two in a row 1408; have a 89 % probability vs the original branch. 1409; CHECK-LABEL: test_forked_hot_diamond_stays_hot 1410; CHECK: %entry 1411; CHECK: %then1 1412; CHECK: %then2 1413; CHECK: %fork1 1414; CHECK: %else1 1415; CHECK: %else2 1416; CHECK: %fork2 1417; CHECK: %exit 1418entry: 1419 %gep1 = getelementptr i32, i32* %a, i32 1 1420 %val1 = load i32, i32* %gep1 1421 %cond1 = icmp ugt i32 %val1, 1 1422 br i1 %cond1, label %then1, label %else1, !prof !10 1423 1424then1: 1425 call void @hot_function() 1426 %gep2 = getelementptr i32, i32* %a, i32 2 1427 %val2 = load i32, i32* %gep2 1428 %cond2 = icmp ugt i32 %val2, 2 1429 br i1 %cond2, label %then2, label %else2, !prof !10 1430 1431else1: 1432 call void @cold_function() 1433 br label %fork1 1434 1435then2: 1436 call void @hot_function() 1437 %gep3 = getelementptr i32, i32* %a, i32 3 1438 %val3 = load i32, i32* %gep2 1439 %cond3 = icmp ugt i32 %val2, 3 1440 br i1 %cond3, label %fork1, label %fork2, !prof !8 1441 1442else2: 1443 call void @cold_function() 1444 br label %fork2 1445 1446fork1: 1447 call void @a() 1448 br label %exit 1449 1450fork2: 1451 call void @b() 1452 br label %exit 1453 1454exit: 1455 call void @hot_function() 1456 ret void 1457} 1458 1459!5 = !{!"branch_weights", i32 84, i32 16} 1460!6 = !{!"function_entry_count", i32 10} 1461!7 = !{!"branch_weights", i32 60, i32 40} 1462!8 = !{!"branch_weights", i32 5001, i32 4999} 1463!9 = !{!"branch_weights", i32 85, i32 15} 1464!10 = !{!"branch_weights", i32 90, i32 10} 1465