1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690
|
# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass branch-relaxation -aarch64-b-offset-bits=64 -aarch64-tbz-offset-bits=9 -aarch64-cbz-offset-bits=9 %s -o - | FileCheck %s
# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass branch-relaxation -aarch64-tbz-offset-bits=9 -aarch64-cbz-offset-bits=9 %s -o - | FileCheck --check-prefix=INDIRECT %s
--- |
declare i32 @bar()
declare i32 @baz()
declare i32 @qux()
define void @relax_tbz(i1 zeroext %0) {
br i1 %0, label %false_block, label %true_block
false_block: ; preds = %1
%2 = call i32 @baz()
br label %end
end: ; preds = %true_block, %false_block
%3 = tail call i32 @qux()
ret void
true_block: ; preds = %1
%4 = call i32 @bar()
br label %end
}
define void @tbz_hot_to_cold(i1 zeroext %0) {
br i1 %0, label %hot_block, label %cold_block
hot_block: ; preds = %1
%2 = call i32 @baz()
br label %end
end: ; preds = %cold_block, %hot_block
%3 = tail call i32 @qux()
ret void
cold_block: ; preds = %1
%4 = call i32 @bar()
br label %end
}
define void @tbz_no_valid_tramp(i1 zeroext %0) {
br i1 %0, label %hot, label %cold
hot: ; preds = %1
%2 = call i32 @baz()
call void asm sideeffect ".space 1024", ""()
br label %end
end: ; preds = %cold, %hot
%3 = tail call i32 @qux()
ret void
cold: ; preds = %1
%4 = call i32 @bar()
br label %end
}
define void @tbz_cold_to_hot(i1 zeroext %0) {
br i1 %0, label %cold_block, label %hot_block
cold_block: ; preds = %1
%2 = call i32 @baz()
br label %end
end: ; preds = %hot_block, %cold_block
%3 = tail call i32 @qux()
ret void
hot_block: ; preds = %1
%4 = call i32 @bar()
br label %end
}
define void @tbz_tramp_pushed_oob(i1 zeroext %0, i1 zeroext %1) {
entry:
%x16 = call i64 asm sideeffect "mov x16, 1", "={x16}"()
br i1 %0, label %unrelaxable, label %cold
unrelaxable: ; preds = %entry
br i1 %1, label %end, label %cold
end: ; preds = %unrelaxable
call void asm sideeffect ".space 996", ""()
call void asm sideeffect "# reg use $0", "{x16}"(i64 %x16)
ret void
cold: ; preds = %entry, %unrelaxable
call void asm sideeffect "# reg use $0", "{x16}"(i64 %x16)
ret void
}
define void @x16_used_cold_to_hot() {
entry:
%x16 = call i64 asm sideeffect "mov x16, 1", "={x16}"()
%cmp = icmp eq i64 %x16, 0
br i1 %cmp, label %hot, label %cold
hot: ; preds = %cold, %entry
call void asm sideeffect "# reg use $0", "{x16}"(i64 %x16)
ret void
cold: ; preds = %entry
call void asm sideeffect ".space 4", ""()
br label %hot
}
define void @all_used_cold_to_hot() {
entry:
%x0 = call i64 asm sideeffect "mov x0, 1", "={x0}"()
%x1 = call i64 asm sideeffect "mov x1, 1", "={x1}"()
%x2 = call i64 asm sideeffect "mov x2, 1", "={x2}"()
%x3 = call i64 asm sideeffect "mov x3, 1", "={x3}"()
%x4 = call i64 asm sideeffect "mov x4, 1", "={x4}"()
%x5 = call i64 asm sideeffect "mov x5, 1", "={x5}"()
%x6 = call i64 asm sideeffect "mov x6, 1", "={x6}"()
%x7 = call i64 asm sideeffect "mov x7, 1", "={x7}"()
%x8 = call i64 asm sideeffect "mov x8, 1", "={x8}"()
%x9 = call i64 asm sideeffect "mov x9, 1", "={x9}"()
%x10 = call i64 asm sideeffect "mov x10, 1", "={x10}"()
%x11 = call i64 asm sideeffect "mov x11, 1", "={x11}"()
%x12 = call i64 asm sideeffect "mov x12, 1", "={x12}"()
%x13 = call i64 asm sideeffect "mov x13, 1", "={x13}"()
%x14 = call i64 asm sideeffect "mov x14, 1", "={x14}"()
%x15 = call i64 asm sideeffect "mov x15, 1", "={x15}"()
%x17 = call i64 asm sideeffect "mov x17, 1", "={x17}"()
%x18 = call i64 asm sideeffect "mov x18, 1", "={x18}"()
%x19 = call i64 asm sideeffect "mov x19, 1", "={x19}"()
%x20 = call i64 asm sideeffect "mov x20, 1", "={x20}"()
%x21 = call i64 asm sideeffect "mov x21, 1", "={x21}"()
%x22 = call i64 asm sideeffect "mov x22, 1", "={x22}"()
%x23 = call i64 asm sideeffect "mov x23, 1", "={x23}"()
%x24 = call i64 asm sideeffect "mov x24, 1", "={x24}"()
%x25 = call i64 asm sideeffect "mov x25, 1", "={x25}"()
%x26 = call i64 asm sideeffect "mov x26, 1", "={x26}"()
%x27 = call i64 asm sideeffect "mov x27, 1", "={x27}"()
%x28 = call i64 asm sideeffect "mov x28, 1", "={x28}"()
br label %cold
exit: ; preds = %cold
call void asm sideeffect "# reg use $0", "{x0}"(i64 %x0)
call void asm sideeffect "# reg use $0", "{x1}"(i64 %x1)
call void asm sideeffect "# reg use $0", "{x2}"(i64 %x2)
call void asm sideeffect "# reg use $0", "{x3}"(i64 %x3)
call void asm sideeffect "# reg use $0", "{x4}"(i64 %x4)
call void asm sideeffect "# reg use $0", "{x5}"(i64 %x5)
call void asm sideeffect "# reg use $0", "{x6}"(i64 %x6)
call void asm sideeffect "# reg use $0", "{x7}"(i64 %x7)
call void asm sideeffect "# reg use $0", "{x8}"(i64 %x8)
call void asm sideeffect "# reg use $0", "{x9}"(i64 %x9)
call void asm sideeffect "# reg use $0", "{x10}"(i64 %x10)
call void asm sideeffect "# reg use $0", "{x11}"(i64 %x11)
call void asm sideeffect "# reg use $0", "{x12}"(i64 %x12)
call void asm sideeffect "# reg use $0", "{x13}"(i64 %x13)
call void asm sideeffect "# reg use $0", "{x14}"(i64 %x14)
call void asm sideeffect "# reg use $0", "{x15}"(i64 %x15)
call void asm sideeffect "# reg use $0", "{x16}"(i64 %x16)
call void asm sideeffect "# reg use $0", "{x17}"(i64 %x17)
call void asm sideeffect "# reg use $0", "{x18}"(i64 %x18)
call void asm sideeffect "# reg use $0", "{x19}"(i64 %x19)
call void asm sideeffect "# reg use $0", "{x20}"(i64 %x20)
call void asm sideeffect "# reg use $0", "{x21}"(i64 %x21)
call void asm sideeffect "# reg use $0", "{x22}"(i64 %x22)
call void asm sideeffect "# reg use $0", "{x23}"(i64 %x23)
call void asm sideeffect "# reg use $0", "{x24}"(i64 %x24)
call void asm sideeffect "# reg use $0", "{x25}"(i64 %x25)
call void asm sideeffect "# reg use $0", "{x26}"(i64 %x26)
call void asm sideeffect "# reg use $0", "{x27}"(i64 %x27)
call void asm sideeffect "# reg use $0", "{x28}"(i64 %x28)
ret void
cold: ; preds = %entry
%x16 = call i64 asm sideeffect "mov x16, 1", "={x16}"()
br label %exit
}
...
---
name: relax_tbz
tracksRegLiveness: true
liveins:
- { reg: '$w0', virtual-reg: '' }
stack:
- { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
body: |
; CHECK-LABEL: name: relax_tbz
; COM: Check that cross-section conditional branches are
; COM: relaxed.
; CHECK: bb.0 (%ir-block.1, bbsections 1):
; CHECK-NEXT: successors: %bb.3
; CHECK: TBNZW
; CHECK-SAME: %bb.3
; CHECK: B %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.3 (%ir-block.1, bbsections 1):
; CHECK-NEXT: successors: %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: B %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1.false_block (bbsections 2):
; CHECK: TCRETURNdi @qux, 0, csr_aarch64_aapcs, implicit $sp
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.true_block (bbsections 3):
; CHECK: TCRETURNdi @qux, 0, csr_aarch64_aapcs, implicit $sp
bb.0 (%ir-block.1, bbsections 1):
successors: %bb.1, %bb.2
liveins: $w0, $lr
early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
TBZW killed renamable $w0, 0, %bb.2
B %bb.1
bb.1.false_block (bbsections 2):
BL @baz, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0
early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
TCRETURNdi @qux, 0, csr_aarch64_aapcs, implicit $sp
bb.2.true_block (bbsections 3):
BL @bar, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0
early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
TCRETURNdi @qux, 0, csr_aarch64_aapcs, implicit $sp
...
---
name: tbz_hot_to_cold
tracksRegLiveness: true
liveins:
- { reg: '$w0', virtual-reg: '' }
stack:
- { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
body: |
; CHECK-LABEL: name: tbz_hot_to_cold
; COM: Check that branch relaxation relaxes cross-section conditional
; COM: branches by creating trampolines after all other hot basic blocks.
; CHECK: bb.0 (%ir-block.1):
; CHECK-NEXT: successors: %bb.1
; CHECK-SAME: , %bb.3
; CHECK: TBZW
; CHECK-SAME: %bb.3
; CHECK: bb.1.hot_block:
; CHECK: TCRETURNdi @qux, 0, csr_aarch64_aapcs, implicit $sp
; CHECK: bb.3 (%ir-block.1):
; CHECK-NEXT: successors: %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: B %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2.cold_block (bbsections Cold):
; CHECK: TCRETURNdi @qux, 0, csr_aarch64_aapcs, implicit $sp
bb.0 (%ir-block.1):
successors: %bb.1, %bb.2
liveins: $w0, $lr
early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
TBZW killed renamable $w0, 0, %bb.2
bb.1.hot_block:
BL @baz, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0
early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
TCRETURNdi @qux, 0, csr_aarch64_aapcs, implicit $sp
bb.2.cold_block (bbsections Cold):
BL @bar, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0
early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
TCRETURNdi @qux, 0, csr_aarch64_aapcs, implicit $sp
...
---
name: tbz_no_valid_tramp
tracksRegLiveness: true
liveins:
- { reg: '$w0', virtual-reg: '' }
stack:
- { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
machineFunctionInfo:
hasRedZone: false
body: |
; CHECK-LABEL: name: tbz_no_valid_tramp
; COM: Check that branch relaxation doesn't insert a trampoline if there is no
; COM: viable insertion location.
; CHECK: bb.0 (%ir-block.1):
; CHECK-NEXT: successors: %bb.1
; CHECK-SAME: , %bb.3
; CHECK: CBNZW
; CHECK-SAME: %bb.1
; CHECK-NEXT: B
; CHECK-SAME: %bb.3
; CHECK: bb.1.hot:
; CHECK: TCRETURNdi
; CHECK: bb.2.cold (bbsections Cold):
; CHECK: TCRETURNdi
bb.0 (%ir-block.1):
successors: %bb.1, %bb.2
liveins: $w0, $lr
early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
CBZW killed renamable $w0, %bb.2
bb.1.hot:
BL @baz, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0
INLINEASM &".space 1024", 1 /* sideeffect attdialect */
early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
TCRETURNdi @qux, 0, csr_aarch64_aapcs, implicit $sp
bb.2.cold (bbsections Cold):
BL @bar, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0
early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
TCRETURNdi @qux, 0, csr_aarch64_aapcs, implicit $sp
...
---
name: tbz_cold_to_hot
tracksRegLiveness: true
liveins:
- { reg: '$w0', virtual-reg: '' }
stack:
- { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
machineFunctionInfo:
hasRedZone: false
body: |
; CHECK-LABEL: name: tbz_cold_to_hot
; COM: Check that relaxation of conditional branches from the Cold section to
; COM: the Hot section doesn't modify the Hot section.
; CHECK: bb.0 (%ir-block.1, bbsections Cold):
; CHECK-NEXT: successors: %bb.1
; CHECK-SAME: , %bb.2
; CHECK: CBNZW
; CHECK-SAME: %bb.1
; CHECK-NEXT: B %bb.2
; CHECK: bb.1.cold_block (bbsections Cold):
; CHECK: TCRETURNdi
; CHECK: bb.2.hot_block:
; CHECK: TCRETURNdi
bb.0 (%ir-block.1, bbsections Cold):
successors: %bb.1, %bb.2
liveins: $w0, $lr
early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
CBZW killed renamable $w0, %bb.2
bb.1.cold_block (bbsections Cold):
BL @baz, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0
early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
TCRETURNdi @qux, 0, csr_aarch64_aapcs, implicit $sp
bb.2.hot_block:
BL @bar, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def dead $w0
early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
TCRETURNdi @qux, 0, csr_aarch64_aapcs, implicit $sp
...
---
name: tbz_tramp_pushed_oob
tracksRegLiveness: true
liveins:
- { reg: '$w0', virtual-reg: '' }
- { reg: '$w1', virtual-reg: '' }
stack:
- { id: 0, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
stack-id: default, callee-saved-register: '$lr', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
machineFunctionInfo:
hasRedZone: false
body: |
; INDIRECT-LABEL: name: tbz_tramp_pushed_oob
; COM: Check that a conditional branch to a trampoline is properly relaxed
; COM: if the trampoline is pushed out of range.
; INDIRECT: bb.0.entry:
; INDIRECT-NEXT: successors: %bb.1
; INDIRECT-SAME: , %[[TRAMP1:bb.[0-9]+]]
; INDIRECT: TBNZW
; INDIRECT-SAME: %bb.1
; INDIRECT-NEXT: B{{ }}
; INDIRECT-SAME: %[[TRAMP1]]
; INDIRECT: bb.1.unrelaxable:
; INDIRECT-NEXT: successors: %bb.2
; INDIRECT-SAME: , %[[TRAMP2:bb.[0-9]+]]
; INDIRECT: TBNZW
; INDIRECT-SAME: %bb.2
; INDIRECT: [[TRAMP2]]
; INDIRECT-NEXT: successors: %bb.6
; INDIRECT: bb.2.end:
; INDIRECT: TCRETURNdi
; INDIRECT: [[TRAMP1]].entry:
; INDIRECT-NEXT: successors: %[[TRAMP1_SPILL:bb.[0-9]+]]
; INDIRECT: [[TRAMP1_SPILL]].entry:
; INDIRECT-NEXT: successors: %[[TRAMP1_RESTORE:bb.[0-9]+]]
; INDIRECT: early-clobber $sp = STRXpre $[[SPILL_REGISTER:x[0-9]+]], $sp, -16
; INDIRECT-NEXT: B %[[TRAMP1_RESTORE:bb.[0-9]+]]
; INDIRECT: [[TRAMP1_RESTORE]].cold (bbsections Cold):
; INDIRECT-NEXT: successors: %bb.3
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: early-clobber $sp, $[[SPILL_REGISTER]] = LDRXpost $sp, 16
; INDIRECT: bb.3.cold (bbsections Cold):
; INDIRECT: TCRETURNdi
bb.0.entry (%ir-block.entry):
successors: %bb.1, %bb.3
liveins: $w0, $w1, $lr
early-clobber $sp = frame-setup STRXpre killed $lr, $sp, -16 :: (store (s64) into %stack.0)
INLINEASM &"mov x16, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x16
TBZW killed renamable $w0, 0, %bb.3
bb.1.unrelaxable:
successors: %bb.2, %bb.3
liveins: $w1, $x16
TBNZW killed renamable $w1, 0, %bb.2
B %bb.3
bb.2.end:
liveins: $x16
INLINEASM &".space 996", 1 /* sideeffect attdialect */
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x16
early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
TCRETURNdi @qux, 0, csr_aarch64_aapcs, implicit $sp
bb.3.cold (bbsections Cold):
liveins: $x16
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x16
early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 16 :: (load (s64) from %stack.0)
TCRETURNdi @qux, 0, csr_aarch64_aapcs, implicit $sp
...
name: x16_used_cold_to_hot
tracksRegLiveness: true
liveins: []
machineFunctionInfo:
hasRedZone: false
body: |
; INDIRECT-LABEL: name: x16_used_cold_to_hot
; COM: Check that unconditional branches from the cold section to
; COM: the hot section manually insert indirect branches if x16
; COM: isn't available but there is still a free register.
; INDIRECT: bb.0.entry:
; INDIRECT-NEXT: successors: %bb.1
; INDIRECT-SAME: , %bb.3
; INDIRECT: TBZW killed renamable $w8, 0, %bb.1
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: bb.3.entry:
; INDIRECT-NEXT: successors: %bb.4
; INDIRECT-NEXT: liveins: $x16
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: early-clobber $sp = STRXpre $[[SPILL_REGISTER]], $sp, -16
; INDIRECT-NEXT: B %bb.4
; INDIRECT: bb.1.hot:
; INDIRECT-NEXT: liveins: $x16
; INDIRECT: killed $x16
; INDIRECT: RET undef $lr
; INDIRECT: bb.4.cold (bbsections Cold):
; INDIRECT-NEXT: successors: %bb.2
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: early-clobber $sp, $[[SPILL_REGISTER]] = LDRXpost $sp, 16
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: bb.2.cold (bbsections Cold):
; INDIRECT-NEXT: successors: %bb.5
; INDIRECT-NEXT: liveins: $x16
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: INLINEASM &".space 4", 1 /* sideeffect attdialect */
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: bb.5.cold (bbsections Cold):
; INDIRECT-NEXT: successors: %bb.1
; INDIRECT-NEXT: liveins: $x16
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: $[[SCAVENGED_REGISTER:x[0-9]+]] = ADRP target-flags(aarch64-page) <mcsymbol >
; INDIRECT-NEXT: $[[SCAVENGED_REGISTER]] = ADDXri $[[SCAVENGED_REGISTER]], target-flags(aarch64-pageoff, aarch64-nc) <mcsymbol >, 0
; INDIRECT-NEXT: BR $[[SCAVENGED_REGISTER]]
bb.0.entry:
successors: %bb.1, %bb.2
$sp = frame-setup SUBXri $sp, 16, 0
INLINEASM &"mov x16, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x16
dead renamable $x8 = SUBSXri $x16, 0, 0, implicit-def $nzcv
renamable $w8 = CSINCWr $wzr, $wzr, 1, implicit killed $nzcv
TBZW killed renamable $w8, 0, %bb.1
B %bb.2
bb.1.hot:
liveins: $x16
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x16
$sp = frame-destroy ADDXri $sp, 16, 0
RET undef $lr
bb.2.cold (bbsections Cold):
successors: %bb.1
liveins: $x16
INLINEASM &".space 4", 1 /* sideeffect attdialect */
B %bb.1
...
---
name: all_used_cold_to_hot
tracksRegLiveness: true
stack:
- { id: 0, name: '', type: spill-slot, offset: -8, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '$x19', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
- { id: 1, name: '', type: spill-slot, offset: -16, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '$x20', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
- { id: 2, name: '', type: spill-slot, offset: -24, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '$x21', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
- { id: 3, name: '', type: spill-slot, offset: -32, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '$x22', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
- { id: 4, name: '', type: spill-slot, offset: -40, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '$x23', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
- { id: 5, name: '', type: spill-slot, offset: -48, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '$x24', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
- { id: 6, name: '', type: spill-slot, offset: -56, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '$x25', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
- { id: 7, name: '', type: spill-slot, offset: -64, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '$x26', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
- { id: 8, name: '', type: spill-slot, offset: -72, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '$x27', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
- { id: 9, name: '', type: spill-slot, offset: -80, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '$x28', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
- { id: 10, name: '', type: spill-slot, offset: -96, size: 8, alignment: 16,
stack-id: default, callee-saved-register: '$fp', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
machineFunctionInfo:
hasRedZone: false
body: |
; INDIRECT-LABEL: name: all_used_cold_to_hot
; COM: Check that unconditional branches from the cold section to
; COM: the hot section spill x16 and defer indirect branch
; COM: insertion to the linker if there are no free general-purpose
; COM: registers.
; INDIRECT: bb.0.entry:
; INDIRECT-NEXT: successors: %bb.3
; INDIRECT-NEXT: liveins: $fp, $x27, $x28, $x25, $x26, $x23, $x24, $x21, $x22, $x19, $x20
; INDIRECT-COUNT-29: INLINEASM &"mov
; INDIRECT-NEXT: {{ $}}
; INDIRECT: bb.3.entry:
; INDIRECT-NEXT: successors: %bb.2
; INDIRECT-NEXT: liveins: $fp, $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8,
; INDIRECT-SAME: $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x17, $x18, $x19,
; INDIRECT-SAME: $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27, $x28
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: B %bb.2
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: bb.1.exit:
; INDIRECT-NEXT: liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9,
; INDIRECT-SAME: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $x18, $x19,
; INDIRECT-SAME: $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27, $x28, $fp
; INDIRECT-NEXT: {{ $}}
; INDIRECT-COUNT-30: INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed
; INDIRECT: RET undef $lr
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: bb.6.exit:
; INDIRECT-NEXT: successors: %bb.7(0x80000000)
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: early-clobber $sp, $[[SPILL_REGISTER]] = LDRXpost $sp, 16
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: bb.7.exit:
; INDIRECT-NEXT: successors: %bb.1(0x80000000)
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: B %bb.1
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: bb.2.cold (bbsections Cold):
; INDIRECT-NEXT: successors: %bb.5
; INDIRECT-NEXT: liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9,
; INDIRECT-SAME: $x10, $x11, $x12, $x13, $x14, $x15, $x17, $x18, $x19, $x20,
; INDIRECT-SAME: $x21, $x22, $x23, $x24, $x25, $x26, $x27, $x28, $fp
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: INLINEASM &"mov x16, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x16
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: bb.5.cold (bbsections Cold):
; INDIRECT-NEXT: successors: %bb.6
; INDIRECT-NEXT: liveins: $fp, $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8,
; INDIRECT-SAME: $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $x18,
; INDIRECT-SAME: $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27, $x28
; INDIRECT-NEXT: {{ $}}
; INDIRECT-NEXT: early-clobber $sp = STRXpre $[[SPILL_REGISTER]], $sp, -16
; INDIRECT-NEXT: B %bb.6
bb.0.entry:
successors: %bb.2
liveins: $fp, $x27, $x28, $x25, $x26, $x23, $x24, $x21, $x22, $x19, $x20
$sp = frame-setup SUBXri $sp, 112, 0
frame-setup STRXui killed $fp, $sp, 2 :: (store (s64) into %stack.10)
frame-setup STPXi killed $x28, killed $x27, $sp, 4 :: (store (s64) into %stack.9), (store (s64) into %stack.8)
frame-setup STPXi killed $x26, killed $x25, $sp, 6 :: (store (s64) into %stack.7), (store (s64) into %stack.6)
frame-setup STPXi killed $x24, killed $x23, $sp, 8 :: (store (s64) into %stack.5), (store (s64) into %stack.4)
frame-setup STPXi killed $x22, killed $x21, $sp, 10 :: (store (s64) into %stack.3), (store (s64) into %stack.2)
frame-setup STPXi killed $x20, killed $x19, $sp, 12 :: (store (s64) into %stack.1), (store (s64) into %stack.0)
INLINEASM &"mov x0, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x0
INLINEASM &"mov x1, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x1
INLINEASM &"mov x2, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x2
INLINEASM &"mov x3, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x3
INLINEASM &"mov x4, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x4
INLINEASM &"mov x5, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x5
INLINEASM &"mov x6, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x6
INLINEASM &"mov x7, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x7
INLINEASM &"mov x8, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x8
INLINEASM &"mov x9, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x9
INLINEASM &"mov x10, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x10
INLINEASM &"mov x11, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x11
INLINEASM &"mov x12, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x12
INLINEASM &"mov x13, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x13
INLINEASM &"mov x14, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x14
INLINEASM &"mov x15, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x15
INLINEASM &"mov x17, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x17
INLINEASM &"mov x18, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x18
INLINEASM &"mov x19, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x19
INLINEASM &"mov x20, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x20
INLINEASM &"mov x21, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x21
INLINEASM &"mov x22, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x22
INLINEASM &"mov x23, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x23
INLINEASM &"mov x24, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x24
INLINEASM &"mov x25, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x25
INLINEASM &"mov x26, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x26
INLINEASM &"mov x27, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x27
INLINEASM &"mov x28, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x28
INLINEASM &"mov fp, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $fp
B %bb.2
bb.1.exit:
liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27, $x28, $fp
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x0
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x1
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x2
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x3
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x4
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x5
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x6
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x7
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x8
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x9
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x10
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x11
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x12
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x13
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x14
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x15
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x16
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x17
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x18
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x19
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x20
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x21
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x22
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x23
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x24
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x25
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x26
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x27
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $x28
INLINEASM &"# reg use $0", 1 /* sideeffect attdialect */, 9 /* reguse */, killed $fp
$x20, $x19 = frame-destroy LDPXi $sp, 12 :: (load (s64) from %stack.1), (load (s64) from %stack.0)
$x22, $x21 = frame-destroy LDPXi $sp, 10 :: (load (s64) from %stack.3), (load (s64) from %stack.2)
$x24, $x23 = frame-destroy LDPXi $sp, 8 :: (load (s64) from %stack.5), (load (s64) from %stack.4)
$x26, $x25 = frame-destroy LDPXi $sp, 6 :: (load (s64) from %stack.7), (load (s64) from %stack.6)
$x28, $x27 = frame-destroy LDPXi $sp, 4 :: (load (s64) from %stack.9), (load (s64) from %stack.8)
$fp = frame-destroy LDRXui $sp, 2 :: (load (s64) from %stack.10)
$sp = frame-destroy ADDXri $sp, 112, 0
RET undef $lr
bb.2.cold (bbsections Cold):
successors: %bb.1
liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x17, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27, $x28, $fp
INLINEASM &"mov x16, 1", 1 /* sideeffect attdialect */, 10 /* regdef */, implicit-def $x16
B %bb.1
...
|