forked from OSchip/llvm-project
582 lines
20 KiB
YAML
582 lines
20 KiB
YAML
# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass=prologepilog %s -o - | FileCheck %s
|
|
#
|
|
# Test allocation and deallocation of SVE objects on the stack,
|
|
# as well as using a combination of scalable and non-scalable
|
|
# offsets to access the SVE on the stack.
|
|
#
|
|
# SVE objects are allocated below the (scalar) callee saves,
|
|
# and above spills/locals and the alignment gap, e.g.
|
|
#
|
|
# +-------------+
|
|
# | stack arg |
|
|
# +-------------+ <- SP before call
|
|
# | Callee Saves|
|
|
# | Frame record| (if available)
|
|
# |-------------| <- FP (if available)
|
|
# | SVE area |
|
|
# +-------------+
|
|
# |/////////////| alignment gap.
|
|
# | : |
|
|
# | Stack objs |
|
|
# | : |
|
|
# +-------------+ <- SP after call and frame-setup
|
|
#
|
|
--- |
|
|
|
|
define void @test_allocate_sve() nounwind { entry: unreachable }
|
|
define void @test_allocate_sve_gpr_callee_saves() nounwind { entry: unreachable }
|
|
define void @test_allocate_sve_gpr_realigned() nounwind { entry: unreachable }
|
|
define void @test_address_sve() nounwind { entry: unreachable }
|
|
define void @test_address_sve_fp() nounwind { entry: unreachable }
|
|
define void @test_stack_arg_sve() nounwind { entry: unreachable }
|
|
define void @test_address_sve_out_of_range() nounwind { entry: unreachable }
|
|
define aarch64_sve_vector_pcs void @save_restore_pregs_sve() nounwind { entry: unreachable }
|
|
define aarch64_sve_vector_pcs void @save_restore_zregs_sve() nounwind { entry: unreachable }
|
|
define aarch64_sve_vector_pcs void @save_restore_sve() nounwind { entry: unreachable }
|
|
define aarch64_sve_vector_pcs void @save_restore_sve_realign() nounwind { entry: unreachable }
|
|
define aarch64_sve_vector_pcs void @frame_layout() nounwind { entry: unreachable }
|
|
|
|
...
|
|
# +----------+
|
|
# |scratchreg| // x29 is used as scratch reg.
|
|
# +----------+
|
|
# | %fixed- | // scalable SVE object of n * 18 bytes, aligned to 16 bytes,
|
|
# | stack.0 | // to be materialized with 2*ADDVL (<=> 2 * n * 16bytes)
|
|
# +----------+
|
|
# | %stack.0 | // not scalable
|
|
# +----------+ <- SP
|
|
|
|
# CHECK-LABEL: name: test_allocate_sve
|
|
# CHECK: stackSize: 32
|
|
|
|
# CHECK: bb.0.entry:
|
|
# CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -16
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -2
|
|
# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
|
|
|
|
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 2
|
|
# CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
|
|
# CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 16
|
|
# CHECK-NEXT: RET_ReallyLR
|
|
name: test_allocate_sve
|
|
fixedStack:
|
|
- { id: 0, stack-id: sve-vec, size: 18, alignment: 2, offset: -18 }
|
|
stack:
|
|
- { id: 0, stack-id: default, size: 16, alignment: 8 }
|
|
body: |
|
|
bb.0.entry:
|
|
RET_ReallyLR
|
|
---
|
|
...
|
|
# +----------+
|
|
# | x20, x21 | // callee saves
|
|
# |scratchreg| // x29 is used as scratch reg.
|
|
# +----------+
|
|
# | %fixed- | // scalable objects
|
|
# | stack.0 |
|
|
# +----------+
|
|
# | %stack.0 | // not scalable
|
|
# +----------+ <- SP
|
|
|
|
# CHECK-LABEL: name: test_allocate_sve_gpr_callee_saves
|
|
# CHECK: stackSize: 48
|
|
|
|
# CHECK: bb.0.entry:
|
|
# CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -32
|
|
# CHECK-NEXT: frame-setup STPXi killed $x21, killed $x20, $sp, 2
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -2
|
|
# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
|
|
# CHECK-NEXT: $x20 = IMPLICIT_DEF
|
|
# CHECK-NEXT: $x21 = IMPLICIT_DEF
|
|
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 2
|
|
# CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
|
|
# CHECK-NEXT: $x21, $x20 = frame-destroy LDPXi $sp, 2
|
|
# CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 32
|
|
# CHECK-NEXT: RET_ReallyLR
|
|
name: test_allocate_sve_gpr_callee_saves
|
|
fixedStack:
|
|
- { id: 0, stack-id: sve-vec, size: 18, alignment: 2, offset: -18 }
|
|
stack:
|
|
- { id: 0, stack-id: default, size: 16, alignment: 8 }
|
|
body: |
|
|
bb.0.entry:
|
|
$x20 = IMPLICIT_DEF
|
|
$x21 = IMPLICIT_DEF
|
|
RET_ReallyLR
|
|
---
|
|
...
|
|
# +----------+
|
|
# | lr, fp | // frame record
|
|
# +----------+ <- FP
|
|
# | %fixed- | // scalable objects
|
|
# | stack.0 |
|
|
# +----------+
|
|
# |//////////| // alignment gap
|
|
# | %stack.0 | // not scalable
|
|
# +----------+ <- SP
|
|
# CHECK-LABEL: name: test_allocate_sve_gpr_realigned
|
|
# CHECK: stackSize: 32
|
|
|
|
# CHECK: bb.0.entry:
|
|
# CHECK-NEXT: $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2
|
|
# CHECK-NEXT: $fp = frame-setup ADDXri $sp, 0, 0
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -2
|
|
# CHECK-NEXT: $[[TMP:x[0-9]+]] = frame-setup SUBXri $sp, 16, 0
|
|
# CHECK-NEXT: $sp = ANDXri killed $[[TMP]]
|
|
# CHECK-NEXT: $sp = frame-destroy ADDXri $fp, 0, 0
|
|
# CHECK-NEXT: $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2
|
|
# CHECK-NEXT: RET_ReallyLR
|
|
name: test_allocate_sve_gpr_realigned
|
|
fixedStack:
|
|
- { id: 0, stack-id: sve-vec, size: 18, alignment: 2, offset: -18 }
|
|
stack:
|
|
- { id: 0, stack-id: default, size: 16, alignment: 32 }
|
|
body: |
|
|
bb.0.entry:
|
|
RET_ReallyLR
|
|
---
|
|
...
|
|
# +----------+
|
|
# | x20, x21 | // callee saves
|
|
# +----------+
|
|
# | %stack.0 | // scalable @ SP + 16b + 32 scalable bytes
|
|
# | %stack.1 | // scalable @ SP + 16b + 16 scalable bytes
|
|
# | %stack.2 | // scalable @ SP + 16b + 14 scalable bytes
|
|
# +----------+
|
|
# | %stack.0 | // not scalable
|
|
# +----------+ <- SP
|
|
|
|
# CHECK-LABEL: name: test_address_sve
|
|
# CHECK: stackSize: 32
|
|
|
|
# CHECK: bb.0.entry:
|
|
# CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -16
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -3
|
|
# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
|
|
|
|
# CHECK-NEXT: $[[TMP:x[0-9]+]] = ADDXri $sp, 16
|
|
# CHECK-NEXT: STR_ZXI $z0, killed $[[TMP]], 2
|
|
# CHECK-NEXT: $[[TMP:x[0-9]+]] = ADDXri $sp, 16
|
|
# CHECK-NEXT: STR_ZXI $z1, killed $[[TMP]], 1
|
|
# CHECK-NEXT: $[[TMP:x[0-9]+]] = ADDXri $sp, 16
|
|
# CHECK-NEXT: STR_PXI $p0, killed $[[TMP]], 7
|
|
|
|
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 3
|
|
# CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
|
|
# CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 16
|
|
# CHECK-NEXT: RET_ReallyLR
|
|
name: test_address_sve
|
|
frameInfo:
|
|
maxAlignment: 16
|
|
fixedStack:
|
|
- { id: 0, stack-id: sve-vec, size: 16, alignment: 8, offset: -16 }
|
|
- { id: 1, stack-id: sve-vec, size: 16, alignment: 8, offset: -32 }
|
|
- { id: 2, stack-id: sve-vec, size: 2, alignment: 2, offset: -34 }
|
|
stack:
|
|
- { id: 0, stack-id: default, size: 16, alignment: 8 }
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: $z0, $z1, $p0
|
|
|
|
STR_ZXI $z0, %fixed-stack.0, 0
|
|
STR_ZXI $z1, %fixed-stack.1, 0
|
|
STR_PXI $p0, %fixed-stack.2, 0
|
|
|
|
RET_ReallyLR
|
|
---
|
|
...
|
|
# +-----------+
|
|
# | x20, x21 | // callee saves
|
|
# | lr, fp | // frame record
|
|
# +-----------+ <- FP
|
|
# | %fstack.0 | // scalable @ FP - 16 scalable bytes
|
|
# | %fstack.1 | // scalable @ FP - 32 scalable bytes
|
|
# | %fstack.2 | // scalable @ FP - 34 scalable bytes
|
|
# +-----------+
|
|
# | %stack.0 | // not scalable
|
|
# +-----------+ <- SP
|
|
|
|
# CHECK-LABEL: name: test_address_sve_fp
|
|
# CHECK: stackSize: 32
|
|
|
|
# CHECK: bb.0.entry:
|
|
# CHECK-NEXT: $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2
|
|
# CHECK-NEXT: $fp = frame-setup ADDXri $sp, 0, 0
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -3
|
|
# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
|
|
|
|
# CHECK-NEXT: STR_ZXI $z0, $fp, -1
|
|
# CHECK-NEXT: STR_ZXI $z1, $fp, -2
|
|
# CHECK-NEXT: STR_PXI $p0, $fp, -17
|
|
|
|
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 3
|
|
# CHECK: $sp = frame-destroy ADDXri $sp, 16, 0
|
|
# CHECK-NEXT: $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2
|
|
# CHECK-NEXT: RET_ReallyLR
|
|
name: test_address_sve_fp
|
|
frameInfo:
|
|
maxAlignment: 16
|
|
isFrameAddressTaken: true
|
|
fixedStack:
|
|
- { id: 0, stack-id: sve-vec, size: 16, alignment: 8, offset: -16 }
|
|
- { id: 1, stack-id: sve-vec, size: 16, alignment: 8, offset: -32 }
|
|
- { id: 2, stack-id: sve-vec, size: 2, alignment: 2, offset: -34 }
|
|
stack:
|
|
- { id: 0, stack-id: default, size: 16, alignment: 8 }
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: $z0, $z1, $p0
|
|
|
|
STR_ZXI $z0, %fixed-stack.0, 0
|
|
STR_ZXI $z1, %fixed-stack.1, 0
|
|
STR_PXI $p0, %fixed-stack.2, 0
|
|
|
|
RET_ReallyLR
|
|
---
|
|
...
|
|
# +-----------+
|
|
# | %fstack.1 | // stack arg @ SP + 16 scalable bytes + 32 bytes.
|
|
# +-----------+
|
|
# |callee save| // register saved as scratch reg.
|
|
# +-----------+
|
|
# | %fstack.1 | // vector of 16 scalable bytes
|
|
# +---------- +
|
|
# | %stack.0 | // not scalable, 16 bytes
|
|
# +-----------+ <- SP
|
|
# CHECK-LABEL: name: test_stack_arg_sve
|
|
# CHECK: stackSize: 32
|
|
|
|
# CHECK: bb.0.entry:
|
|
# CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -16
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -1
|
|
# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
|
|
|
|
# CHECK: $[[TMP:x[0-9]+]] = ADDVL_XXI $sp, 1
|
|
# CHECK-NEXT: $x0 = LDRXui killed $[[TMP]], 4
|
|
|
|
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 1
|
|
# CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
|
|
# CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 16
|
|
# CHECK-NEXT: RET_ReallyLR
|
|
name: test_stack_arg_sve
|
|
fixedStack:
|
|
- { id: 0, stack-id: default, size: 16, alignment: 16, offset: 0 }
|
|
- { id: 1, stack-id: sve-vec, size: 16, alignment: 16, offset: -16 }
|
|
stack:
|
|
- { id: 0, stack-id: default, size: 16, alignment: 16 }
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: $x0
|
|
|
|
$x0 = LDRXui %fixed-stack.0, 0
|
|
RET_ReallyLR
|
|
---
|
|
...
|
|
# Test that the address to access an SVE data vector at an offset that
|
|
# does not fit its immediate, is correctly materialized.
|
|
# +----------+
|
|
# |calleesave| // register saved as scratch reg.
|
|
# +----------+
|
|
# | %stack.0 | // one SVE data object @ SP + 256 scalable bytes.
|
|
# |::::::::::|
|
|
# |: :|
|
|
# |:%stack.1:| // Large object
|
|
# |: :|
|
|
# |::::::::::|
|
|
# +----------+ <- SP
|
|
# CHECK-LABEL: name: test_address_sve_out_of_range
|
|
# CHECK: stackSize: 16
|
|
|
|
# CHECK: bb.0.entry:
|
|
# CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -16
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -1
|
|
|
|
# CHECK-NEXT: $[[TMP2:x[0-9]+]] = ADDVL_XXI $sp, 1
|
|
# CHECK-NEXT: STR_ZXI $z0, killed $[[TMP2]], 255
|
|
|
|
# CHECK-NEXT: $[[TMP2:x[0-9]+]] = ADDPL_XXI $sp, 1
|
|
# CHECK-NEXT: STR_PXI $p0, killed $[[TMP2]], 255
|
|
|
|
# CHECK: $sp = frame-destroy ADDVL_XXI $sp, 31
|
|
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31
|
|
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31
|
|
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31
|
|
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31
|
|
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31
|
|
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31
|
|
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 31
|
|
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 9
|
|
# CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 16
|
|
# CHECK-NEXT: RET_ReallyLR
|
|
name: test_address_sve_out_of_range
|
|
frameInfo:
|
|
maxAlignment: 16
|
|
fixedStack:
|
|
- { id: 0, stack-id: sve-vec, size: 16, alignment: 16, offset: -16 }
|
|
- { id: 1, stack-id: sve-vec, size: 3584, alignment: 16, offset: -3600 }
|
|
- { id: 2, stack-id: sve-vec, size: 512, alignment: 16, offset: -4112 }
|
|
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: $z0, $p0
|
|
|
|
STR_ZXI $z0, %fixed-stack.0, 0
|
|
STR_PXI $p0, %fixed-stack.1, 0
|
|
|
|
RET_ReallyLR
|
|
---
|
|
...
|
|
# CHECK-LABEL: name: save_restore_pregs_sve
|
|
# CHECK: $sp = frame-setup ADDVL_XXI $sp, -1
|
|
# CHECK: frame-setup STR_PXI killed $p6, $sp, 5
|
|
# CHECK: frame-setup STR_PXI killed $p5, $sp, 6
|
|
# CHECK: frame-setup STR_PXI killed $p4, $sp, 7
|
|
# CHECK: $sp = frame-setup SUBXri $sp, 32, 0
|
|
|
|
# CHECK: $sp = frame-destroy ADDXri $sp, 32, 0
|
|
# CHECK: $p6 = frame-destroy LDR_PXI $sp, 5
|
|
# CHECK: $p5 = frame-destroy LDR_PXI $sp, 6
|
|
# CHECK: $p4 = frame-destroy LDR_PXI $sp, 7
|
|
# CHECK: $sp = frame-destroy ADDVL_XXI $sp, 1
|
|
# CHECK: RET_ReallyLR
|
|
name: save_restore_pregs_sve
|
|
stack:
|
|
- { id: 0, stack-id: default, size: 32, alignment: 16 }
|
|
body: |
|
|
bb.0.entry:
|
|
|
|
$p4 = IMPLICIT_DEF
|
|
$p5 = IMPLICIT_DEF
|
|
$p6 = IMPLICIT_DEF
|
|
|
|
RET_ReallyLR
|
|
---
|
|
...
|
|
# CHECK-LABEL: name: save_restore_zregs_sve
|
|
# CHECK: $sp = frame-setup ADDVL_XXI $sp, -3
|
|
# CHECK: frame-setup STR_ZXI killed $z10, $sp, 0
|
|
# CHECK: frame-setup STR_ZXI killed $z9, $sp, 1
|
|
# CHECK: frame-setup STR_ZXI killed $z8, $sp, 2
|
|
# CHECK: $sp = frame-setup SUBXri $sp, 32, 0
|
|
|
|
# CHECK: $sp = frame-destroy ADDXri $sp, 32, 0
|
|
# CHECK: $z10 = frame-destroy LDR_ZXI $sp, 0
|
|
# CHECK: $z9 = frame-destroy LDR_ZXI $sp, 1
|
|
# CHECK: $z8 = frame-destroy LDR_ZXI $sp, 2
|
|
# CHECK: $sp = frame-destroy ADDVL_XXI $sp, 3
|
|
# CHECK: RET_ReallyLR
|
|
name: save_restore_zregs_sve
|
|
stack:
|
|
- { id: 0, stack-id: default, size: 32, alignment: 16 }
|
|
body: |
|
|
bb.0.entry:
|
|
|
|
$z8 = IMPLICIT_DEF
|
|
$z9 = IMPLICIT_DEF
|
|
$z10 = IMPLICIT_DEF
|
|
|
|
RET_ReallyLR
|
|
---
|
|
...
|
|
# Test allocation/deallocation of the stack frame together with the
|
|
# saving/restoring of callee save registers. Fixed-stack objects
|
|
# are allocated before the callee-saves.
|
|
# This also adds some non-SVE callee-saves, to ensure that those are
|
|
# paired correctly.
|
|
#
|
|
# CHECK-LABEL: name: save_restore_sve
|
|
# CHECK: $sp = frame-setup STPXpre killed ${{[a-z0-9]+}}, killed $x21, $sp, -4
|
|
# CHECK: frame-setup STPXi killed $x20, killed $x19, $sp, 2
|
|
# CHECK: $sp = frame-setup ADDVL_XXI $sp, -19
|
|
# CHECK: frame-setup STR_PXI killed $p15, $sp, 4
|
|
# CHECK: frame-setup STR_PXI killed $p14, $sp, 5
|
|
# CHECK: frame-setup STR_PXI killed $p5, $sp, 14
|
|
# CHECK: frame-setup STR_PXI killed $p4, $sp, 15
|
|
# CHECK: frame-setup STR_ZXI killed $z23, $sp, 2
|
|
# CHECK: frame-setup STR_ZXI killed $z22, $sp, 3
|
|
# CHECK: frame-setup STR_ZXI killed $z9, $sp, 16
|
|
# CHECK: frame-setup STR_ZXI killed $z8, $sp, 17
|
|
# CHECK: $sp = frame-setup SUBXri $sp, 32, 0
|
|
|
|
# CHECK: $sp = frame-destroy ADDXri $sp, 32, 0
|
|
# CHECK: $p15 = frame-destroy LDR_PXI $sp, 4
|
|
# CHECK: $p14 = frame-destroy LDR_PXI $sp, 5
|
|
# CHECK: $p5 = frame-destroy LDR_PXI $sp, 14
|
|
# CHECK: $p4 = frame-destroy LDR_PXI $sp, 15
|
|
# CHECK: $z23 = frame-destroy LDR_ZXI $sp, 2
|
|
# CHECK: $z22 = frame-destroy LDR_ZXI $sp, 3
|
|
# CHECK: $z9 = frame-destroy LDR_ZXI $sp, 16
|
|
# CHECK: $z8 = frame-destroy LDR_ZXI $sp, 17
|
|
# CHECK: $sp = frame-destroy ADDVL_XXI $sp, 19
|
|
# CHECK: $x20, $x19 = frame-destroy LDPXi $sp, 2
|
|
# CHECK: $sp, ${{[a-z0-9]+}}, $x21 = frame-destroy LDPXpost $sp, 4
|
|
# CHECK: RET_ReallyLR
|
|
name: save_restore_sve
|
|
fixedStack:
|
|
- { id: 0, stack-id: sve-vec, size: 16, alignment: 16, offset: -16 }
|
|
stack:
|
|
- { id: 0, stack-id: default, size: 32, alignment: 16 }
|
|
body: |
|
|
bb.0.entry:
|
|
|
|
$z8_z9_z10_z11 = IMPLICIT_DEF
|
|
$z12_z13_z14_z15 = IMPLICIT_DEF
|
|
$z16_z17_z18_z19 = IMPLICIT_DEF
|
|
$z20_z21_z22_z23 = IMPLICIT_DEF
|
|
$z24_z25_z26_z27 = IMPLICIT_DEF
|
|
$z28_z29_z30_z31 = IMPLICIT_DEF
|
|
$p4 = IMPLICIT_DEF
|
|
$p5 = IMPLICIT_DEF
|
|
$p6 = IMPLICIT_DEF
|
|
$p7 = IMPLICIT_DEF
|
|
$p8 = IMPLICIT_DEF
|
|
$p9 = IMPLICIT_DEF
|
|
$p10 = IMPLICIT_DEF
|
|
$p11 = IMPLICIT_DEF
|
|
$p12 = IMPLICIT_DEF
|
|
$p13 = IMPLICIT_DEF
|
|
$p14 = IMPLICIT_DEF
|
|
$p15 = IMPLICIT_DEF
|
|
|
|
$x19 = IMPLICIT_DEF
|
|
$x20 = IMPLICIT_DEF
|
|
$x21 = IMPLICIT_DEF
|
|
|
|
RET_ReallyLR
|
|
---
|
|
...
|
|
# Test allocation/deallocation of the stack frame together with the
|
|
# saving/restoring of callee save registers. Fixed-stack objects
|
|
# are allocated before the callee-saves.
|
|
#
|
|
# CHECK-LABEL: name: save_restore_sve_realign
|
|
# CHECK: $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2
|
|
# CHECK-NEXT: $fp = frame-setup ADDXri $sp, 0, 0
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -19
|
|
# CHECK-NEXT: STR_PXI killed $p15, $sp, 4
|
|
# CHECK-NEXT: STR_PXI killed $p14, $sp, 5
|
|
# CHECK: STR_PXI killed $p5, $sp, 14
|
|
# CHECK-NEXT: STR_PXI killed $p4, $sp, 15
|
|
# CHECK-NEXT: STR_ZXI killed $z23, $sp, 2
|
|
# CHECK-NEXT: STR_ZXI killed $z22, $sp, 3
|
|
# CHECK: STR_ZXI killed $z9, $sp, 16
|
|
# CHECK-NEXT: STR_ZXI killed $z8, $sp, 17
|
|
# CHECK-NEXT: $[[TMP:x[0-9]+]] = frame-setup SUBXri $sp, 16, 0
|
|
# CHECK-NEXT: $sp = ANDXri killed $[[TMP]]
|
|
|
|
# CHECK: $sp = frame-destroy ADDVL_XXI $fp, -19
|
|
# CHECK-NEXT: $p15 = frame-destroy LDR_PXI $sp, 4
|
|
# CHECK-NEXT: $p14 = frame-destroy LDR_PXI $sp, 5
|
|
# CHECK: $p5 = frame-destroy LDR_PXI $sp, 14
|
|
# CHECK-NEXT: $p4 = frame-destroy LDR_PXI $sp, 15
|
|
# CHECK-NEXT: $z23 = frame-destroy LDR_ZXI $sp, 2
|
|
# CHECK-NEXT: $z22 = frame-destroy LDR_ZXI $sp, 3
|
|
# CHECK: $z9 = frame-destroy LDR_ZXI $sp, 16
|
|
# CHECK-NEXT: $z8 = frame-destroy LDR_ZXI $sp, 17
|
|
# CHECK-NEXT: $sp = frame-destroy ADDXri $fp, 0, 0
|
|
# CHECK-NEXT: $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2
|
|
# CHECK-NEXT: RET_ReallyLR
|
|
name: save_restore_sve_realign
|
|
fixedStack:
|
|
- { id: 0, stack-id: sve-vec, size: 16, alignment: 16, offset: -16 }
|
|
stack:
|
|
- { id: 0, stack-id: default, size: 16, alignment: 32 }
|
|
body: |
|
|
bb.0.entry:
|
|
|
|
$z8_z9_z10_z11 = IMPLICIT_DEF
|
|
$z12_z13_z14_z15 = IMPLICIT_DEF
|
|
$z16_z17_z18_z19 = IMPLICIT_DEF
|
|
$z20_z21_z22_z23 = IMPLICIT_DEF
|
|
$z24_z25_z26_z27 = IMPLICIT_DEF
|
|
$z28_z29_z30_z31 = IMPLICIT_DEF
|
|
$p4 = IMPLICIT_DEF
|
|
$p5 = IMPLICIT_DEF
|
|
$p6 = IMPLICIT_DEF
|
|
$p7 = IMPLICIT_DEF
|
|
$p8 = IMPLICIT_DEF
|
|
$p9 = IMPLICIT_DEF
|
|
$p10 = IMPLICIT_DEF
|
|
$p11 = IMPLICIT_DEF
|
|
$p12 = IMPLICIT_DEF
|
|
$p13 = IMPLICIT_DEF
|
|
$p14 = IMPLICIT_DEF
|
|
$p15 = IMPLICIT_DEF
|
|
|
|
RET_ReallyLR
|
|
---
|
|
# Frame layout should be:
|
|
# +---------------------+ <- Old SP
|
|
# | callee save z8 |@ -16
|
|
# | callee save z23 |@ -32
|
|
# | callee save p4 |@ -34
|
|
# | callee save p15 |@ -48
|
|
# | id #0 (size 32) |@ -80
|
|
# | id #1 (size 4) |@ -84
|
|
# | id #2 (size 16) |@ -112
|
|
# | id #3 (size 2) |@ -114
|
|
# | id #4 (size 16) |@ -144
|
|
# | id #5 (size 2) |@ -146
|
|
# +- - - - - - - - - - -+ <- New SP @-160
|
|
# CHECK-LABEL: name: frame_layout
|
|
# CHECK: stack:
|
|
# CHECK: - { id: 0, name: '', type: default, offset: -80, size: 32, alignment: 16,
|
|
# CHECK-NEXT: stack-id: sve-vec,
|
|
# CHECK: - { id: 1, name: '', type: default, offset: -84, size: 4, alignment: 2,
|
|
# CHECK-NEXT: stack-id: sve-vec,
|
|
# CHECK: - { id: 2, name: '', type: default, offset: -112, size: 16, alignment: 16,
|
|
# CHECK-NEXT: stack-id: sve-vec,
|
|
# CHECK: - { id: 3, name: '', type: default, offset: -114, size: 2, alignment: 2,
|
|
# CHECK-NEXT: stack-id: sve-vec,
|
|
# CHECK: - { id: 4, name: '', type: spill-slot, offset: -144, size: 16, alignment: 16,
|
|
# CHECK-NEXT: stack-id: sve-vec,
|
|
# CHECK: - { id: 5, name: '', type: spill-slot, offset: -146, size: 2, alignment: 2,
|
|
# CHECK-NEXT: stack-id: sve-vec,
|
|
# CHECK: - { id: 6, name: '', type: spill-slot, offset: -16, size: 16, alignment: 16,
|
|
# CHECK-NEXT: stack-id: sve-vec, callee-saved-register: '$z8',
|
|
# CHECK: - { id: 7, name: '', type: spill-slot, offset: -32, size: 16, alignment: 16,
|
|
# CHECK-NEXT: stack-id: sve-vec, callee-saved-register: '$z23',
|
|
# CHECK: - { id: 8, name: '', type: spill-slot, offset: -34, size: 2, alignment: 2,
|
|
# CHECK-NEXT: stack-id: sve-vec, callee-saved-register: '$p4',
|
|
# CHECK: - { id: 9, name: '', type: spill-slot, offset: -48, size: 2, alignment: 16,
|
|
# CHECK-NEXT: stack-id: sve-vec, callee-saved-register: '$p15',
|
|
# CHECK: - { id: 10, name: '', type: spill-slot, offset: -16, size: 8, alignment: 16,
|
|
# CHECK-NEXT: stack-id: default, callee-saved-register: '$fp',
|
|
#
|
|
# CHECK: bb.0.entry:
|
|
# CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -16
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -3
|
|
# CHECK-NEXT: STR_PXI killed $p15, $sp, 6
|
|
# CHECK-NEXT: STR_PXI killed $p4, $sp, 7
|
|
# CHECK-NEXT: STR_ZXI killed $z23, $sp, 1
|
|
# CHECK-NEXT: STR_ZXI killed $z8, $sp, 2
|
|
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -7
|
|
name: frame_layout
|
|
stack:
|
|
- { id: 0, type: default, size: 32, alignment: 16, stack-id: sve-vec }
|
|
- { id: 1, type: default, size: 4, alignment: 2, stack-id: sve-vec }
|
|
- { id: 2, type: default, size: 16, alignment: 16, stack-id: sve-vec }
|
|
- { id: 3, type: default, size: 2, alignment: 2, stack-id: sve-vec }
|
|
- { id: 4, type: spill-slot, size: 16, alignment: 16, stack-id: sve-vec }
|
|
- { id: 5, type: spill-slot, size: 2, alignment: 2, stack-id: sve-vec }
|
|
body: |
|
|
bb.0.entry:
|
|
|
|
; Trigger some callee saves
|
|
$z8 = IMPLICIT_DEF
|
|
$z23 = IMPLICIT_DEF
|
|
$p4 = IMPLICIT_DEF
|
|
$p15 = IMPLICIT_DEF
|
|
|
|
RET_ReallyLR
|
|
|
|
---
|