# 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
...