| # RUN: llc -mattr=+sve -mtriple=aarch64-none-linux-gnu -run-pass=prologepilog %s -o - | FileCheck %s |
| # RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+sve -start-before=prologepilog %s -o - | FileCheck %s --check-prefix=ASM |
| # RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+sve -start-before=prologepilog %s -filetype=obj -o %t |
| # RUN: llvm-objdump --dwarf=frames %t | FileCheck %s --check-prefix=UNWINDINFO |
| # RUN: rm -rf %t |
| # |
| # 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() { entry: unreachable } |
| define void @test_allocate_sve_gpr_callee_saves() { entry: unreachable } |
| define void @test_allocate_sve_gpr_realigned() { entry: unreachable } |
| define void @test_address_sve() { entry: unreachable } |
| define void @test_address_sve_fp() { entry: unreachable } |
| define void @test_stack_arg_sve() { entry: unreachable } |
| define void @test_address_sve_out_of_range() { entry: unreachable } |
| define void @test_address_gpr_vla() { entry: unreachable } |
| define aarch64_sve_vector_pcs void @save_restore_pregs_sve() { entry: unreachable } |
| define aarch64_sve_vector_pcs void @save_restore_zregs_sve() { entry: unreachable } |
| define aarch64_sve_vector_pcs void @save_restore_sve() { entry: unreachable } |
| define aarch64_sve_vector_pcs void @save_restore_sve_realign() { entry: unreachable } |
| define aarch64_sve_vector_pcs void @frame_layout() { entry: unreachable } |
| define void @fp_relative_index_with_float_save() { entry: unreachable } |
| |
| ... |
| # +----------+ |
| # |scratchreg| // x29 is used as scratch reg. |
| # +----------+ |
| # | %stack.0 | // scalable SVE object of n * 18 bytes, aligned to 16 bytes, |
| # | | // to be materialized with 2*ADDVL (<=> 2 * n * 16bytes) |
| # +----------+ |
| # | %stack.1 | // 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-COUNT-2: frame-setup CFI_INSTRUCTION |
| |
| # 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 |
| |
| # ASM-LABEL: test_allocate_sve: |
| # ASM: .cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x20, 0x22, 0x11, 0x10, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 32 + 16 * VG |
| # ASM-NEXT: .cfi_offset w29, -16 |
| # |
| # UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +32, DW_OP_plus, DW_OP_consts +16, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16 |
| name: test_allocate_sve |
| stack: |
| - { id: 0, stack-id: scalable-vector, size: 18, alignment: 2 } |
| - { id: 1, stack-id: default, size: 16, alignment: 8 } |
| body: | |
| bb.0.entry: |
| RET_ReallyLR |
| --- |
| ... |
| # +----------+ |
| # | x20, x21 | // callee saves |
| # |scratchreg| // x29 is used as scratch reg. |
| # +----------+ |
| # | %stack.0 | // scalable objects |
| # +----------+ |
| # | %stack.1 | // 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-COUNT-4: frame-setup CFI_INSTRUCTION |
| # |
| # 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 |
| # |
| # ASM-LABEL: test_allocate_sve_gpr_callee_saves: |
| # ASM: .cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x30, 0x22, 0x11, 0x10, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 48 + 16 * VG |
| # ASM-NEXT: .cfi_offset w20, -8 |
| # ASM-NEXT: .cfi_offset w21, -16 |
| # ASM-NEXT: .cfi_offset w29, -32 |
| # |
| # UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +48, DW_OP_plus, DW_OP_consts +16, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg20 -8 |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg21 -16 |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg29 -32 |
| name: test_allocate_sve_gpr_callee_saves |
| stack: |
| - { id: 0, stack-id: scalable-vector, size: 18, alignment: 2 } |
| - { id: 1, stack-id: default, size: 16, alignment: 8 } |
| body: | |
| bb.0.entry: |
| $x20 = IMPLICIT_DEF |
| $x21 = IMPLICIT_DEF |
| RET_ReallyLR |
| --- |
| ... |
| # +----------+ |
| # | lr, fp | // frame record |
| # +----------+ <- FP |
| # | %stack.0 | // scalable objects |
| # +----------+ |
| # |//////////| // alignment gap |
| # | %stack.1 | // 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-COUNT-3: frame-setup CFI_INSTRUCTION |
| # CHECK-NEXT: $sp = frame-destroy ADDXri $fp, 0, 0 |
| # CHECK-NEXT: $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2 |
| # CHECK-NEXT: RET_ReallyLR |
| # |
| # ASM-LABEL: test_allocate_sve_gpr_realigned: |
| # ASM: .cfi_def_cfa w29, 16 |
| # ASM-NEXT: .cfi_offset w30, -8 |
| # ASM-NEXT: .cfi_offset w29, -16 |
| # |
| # UNWINDINFO: DW_CFA_def_cfa: reg29 +16 |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg30 -8 |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16 |
| |
| name: test_allocate_sve_gpr_realigned |
| stack: |
| - { id: 0, stack-id: scalable-vector, size: 18, alignment: 2 } |
| - { id: 1, 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.3 | // 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-COUNT-2: frame-setup CFI_INSTRUCTION |
| |
| # 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 |
| # |
| # ASM-LABEL: test_address_sve: |
| # ASM: .cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x20, 0x22, 0x11, 0x18, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 32 + 24 * VG |
| # ASM-NEXT: .cfi_offset w29, -16 |
| # |
| # UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +32, DW_OP_plus, DW_OP_consts +24, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16 |
| |
| name: test_address_sve |
| frameInfo: |
| maxAlignment: 16 |
| stack: |
| - { id: 0, stack-id: scalable-vector, size: 16, alignment: 8 } |
| - { id: 1, stack-id: scalable-vector, size: 16, alignment: 8 } |
| - { id: 2, stack-id: scalable-vector, size: 2, alignment: 2 } |
| - { id: 3, stack-id: default, size: 16, alignment: 8 } |
| body: | |
| bb.0.entry: |
| liveins: $z0, $z1, $p0 |
| |
| STR_ZXI $z0, %stack.0, 0 |
| STR_ZXI $z1, %stack.1, 0 |
| STR_PXI $p0, %stack.2, 0 |
| |
| RET_ReallyLR |
| --- |
| ... |
| # +-----------+ |
| # | x20, x21 | // callee saves |
| # | lr, fp | // frame record |
| # +-----------+ <- FP |
| # | %stack.0 | // scalable @ FP - 16 scalable bytes |
| # | %stack.1 | // scalable @ FP - 32 scalable bytes |
| # | %stack.2 | // scalable @ FP - 34 scalable bytes |
| # +-----------+ |
| # | %stack.3 | // 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-COUNT-3: frame-setup CFI_INSTRUCTION |
| |
| # 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 |
| # |
| # ASM-LABEL: test_address_sve_fp: |
| # ASM: .cfi_def_cfa w29, 16 |
| # ASM-NEXT: .cfi_offset w30, -8 |
| # ASM-NEXT: .cfi_offset w29, -16 |
| # |
| # UNWINDINFO: DW_CFA_def_cfa: reg29 +16 |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg30 -8 |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16 |
| name: test_address_sve_fp |
| frameInfo: |
| maxAlignment: 16 |
| isFrameAddressTaken: true |
| stack: |
| - { id: 0, stack-id: scalable-vector, size: 16, alignment: 8 } |
| - { id: 1, stack-id: scalable-vector, size: 16, alignment: 8 } |
| - { id: 2, stack-id: scalable-vector, size: 2, alignment: 2 } |
| - { id: 3, stack-id: default, size: 16, alignment: 8 } |
| body: | |
| bb.0.entry: |
| liveins: $z0, $z1, $p0 |
| |
| STR_ZXI $z0, %stack.0, 0 |
| STR_ZXI $z1, %stack.1, 0 |
| STR_PXI $p0, %stack.2, 0 |
| |
| RET_ReallyLR |
| --- |
| ... |
| # +-----------+ |
| # | %fstack.1 | // stack arg @ SP + 16 scalable bytes + 32 bytes. |
| # +-----------+ |
| # |callee save| // register saved as scratch reg. |
| # +-----------+ |
| # | %stack.0 | // vector of 16 scalable bytes |
| # +---------- + |
| # | %stack.1 | // 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-COUNT-2: frame-setup CFI_INSTRUCTION |
| |
| # 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 |
| # |
| # ASM-LABEL: test_stack_arg_sve: |
| # ASM: .cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x20, 0x22, 0x11, 0x08, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 32 + 8 * VG |
| # ASM-NEXT: .cfi_offset w29, -16 |
| # |
| # UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +32, DW_OP_plus, DW_OP_consts +8, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16 |
| |
| name: test_stack_arg_sve |
| fixedStack: |
| - { id: 0, stack-id: default, size: 16, alignment: 16, offset: 0 } |
| stack: |
| - { id: 0, stack-id: scalable-vector, size: 16, alignment: 16 } |
| - { id: 1, 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-COUNT-2: frame-setup CFI_INSTRUCTION |
| |
| # 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 |
| # |
| # ASM-LABEL: test_address_sve_out_of_range: |
| # ASM: .cfi_escape 0x0f, 0x0d, 0x8f, 0x00, 0x11, 0x10, 0x22, 0x11, 0x88, 0x10, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 16 + 2056 * VG |
| # ASM-NEXT: .cfi_offset w29, -16 |
| # |
| # UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +16, DW_OP_plus, DW_OP_consts +2056, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16 |
| name: test_address_sve_out_of_range |
| frameInfo: |
| maxAlignment: 16 |
| stack: |
| - { id: 0, stack-id: scalable-vector, size: 16, alignment: 16 } |
| - { id: 1, stack-id: scalable-vector, size: 3584, alignment: 16 } |
| - { id: 2, stack-id: scalable-vector, size: 512, alignment: 16 } |
| |
| body: | |
| bb.0.entry: |
| liveins: $z0, $p0 |
| |
| STR_ZXI $z0, %stack.0, 0 |
| STR_PXI $p0, %stack.1, 0 |
| |
| RET_ReallyLR |
| --- |
| ... |
| # Test that non-SVE objects are accessed from BP when there are |
| # variable length arrays, because it will be more expensive to |
| # access from the FP when there are also SVE objects on the stack. |
| # |
| # +----------+ <- FP |
| # | %stack.0 | // 16 scalable bytes |
| # +----------+ <- @FP - 16 scalable bytes |
| # | %stack.1 | // 16 bytes |
| # +----------+ <- @BP |
| # : %stack.2 : // variable length |
| # +----------+ <- SP |
| |
| # CHECK-LABEL: name: test_address_gpr_vla |
| # CHECK: bb.0.entry: |
| # CHECK: STRXui $xzr, $x19, 0 |
| # CHECK: RET_ReallyLR |
| # |
| # ASM-LABEL: test_address_gpr_vla: |
| # ASM: .cfi_def_cfa w29, 32 |
| # ASM-NEXT: .cfi_offset w19, -16 |
| # ASM-NEXT: .cfi_offset w30, -24 |
| # ASM-NEXT: .cfi_offset w29, -32 |
| # |
| # UNWINDINFO: DW_CFA_def_cfa: reg29 +32 |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg19 -16 |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg30 -24 |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg29 -32 |
| name: test_address_gpr_vla |
| frameInfo: |
| maxAlignment: 16 |
| stack: |
| - { id: 0, stack-id: scalable-vector, size: 16, alignment: 8 } |
| - { id: 1, stack-id: default, size: 16, alignment: 8 } |
| - { id: 2, stack-id: default, type: variable-sized } |
| body: | |
| bb.0.entry: |
| liveins: $xzr |
| |
| STRXui $xzr, %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-COUNT-2: frame-setup CFI_INSTRUCTION |
| |
| # 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 |
| # |
| # ASM-LABEL: save_restore_pregs_sve: |
| # ASM: .cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x30, 0x22, 0x11, 0x08, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 48 + 8 * VG |
| # ASM-NEXT: .cfi_offset w29, -16 |
| # |
| # UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +48, DW_OP_plus, DW_OP_consts +8, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16 |
| 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 STRXpre killed $fp, $sp, -16 |
| # CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -3 |
| # CHECK-NEXT: frame-setup STR_ZXI killed $z10, $sp, 0 |
| # CHECK-NEXT: frame-setup STR_ZXI killed $z9, $sp, 1 |
| # CHECK-NEXT: frame-setup STR_ZXI killed $z8, $sp, 2 |
| # CHECK-NEXT: $sp = frame-setup SUBXri $sp, 32, 0 |
| # CHECK-COUNT-5: frame-setup CFI_INSTRUCTION |
| |
| # CHECK: $sp = frame-destroy ADDXri $sp, 32, 0 |
| # CHECK-NEXT: $z10 = frame-destroy LDR_ZXI $sp, 0 |
| # CHECK-NEXT: $z9 = frame-destroy LDR_ZXI $sp, 1 |
| # CHECK-NEXT: $z8 = frame-destroy LDR_ZXI $sp, 2 |
| # CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 3 |
| # CHECK-NEXT: $sp, $fp = frame-destroy LDRXpost $sp, 16 |
| # CHECK-NEXT: RET_ReallyLR |
| # |
| # ASM-LABEL: save_restore_zregs_sve: |
| # ASM: .cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x30, 0x22, 0x11, 0x18, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 48 + 24 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x48, 0x0a, 0x11, 0x70, 0x22, 0x11, 0x78, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d8 @ cfa - 16 - 8 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x49, 0x0a, 0x11, 0x70, 0x22, 0x11, 0x70, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d9 @ cfa - 16 - 16 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x4a, 0x0a, 0x11, 0x70, 0x22, 0x11, 0x68, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d10 @ cfa - 16 - 24 * VG |
| |
| # UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +48, DW_OP_plus, DW_OP_consts +24, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg72 DW_OP_consts -16, DW_OP_plus, DW_OP_consts -8, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg73 DW_OP_consts -16, DW_OP_plus, DW_OP_consts -16, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg74 DW_OP_consts -16, DW_OP_plus, DW_OP_consts -24, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16 |
| |
| 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, -18 |
| # 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 ADDVL_XXI $sp, -1 |
| # CHECK: $sp = frame-setup SUBXri $sp, 32, 0 |
| # CHECK-COUNT-13: frame-setup CFI_INSTRUCTION |
| |
| # CHECK: $sp = frame-destroy ADDXri $sp, 32, 0 |
| # CHECK: $sp = frame-destroy ADDVL_XXI $sp, 1 |
| # 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, 18 |
| # CHECK: $x20, $x19 = frame-destroy LDPXi $sp, 2 |
| # CHECK: $sp, ${{[a-z0-9]+}}, $x21 = frame-destroy LDPXpost $sp, 4 |
| # CHECK: RET_ReallyLR |
| # |
| # ASM-LABEL: save_restore_sve: |
| # ASM: .cfi_escape 0x0f, 0x0e, 0x8f, 0x00, 0x11, 0xc0, 0x00, 0x22, 0x11, 0x98, 0x01, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 64 + 152 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x48, 0x0a, 0x11, 0x60, 0x22, 0x11, 0x78, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d8 @ cfa - 32 - 8 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x49, 0x0a, 0x11, 0x60, 0x22, 0x11, 0x70, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d9 @ cfa - 32 - 16 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x4a, 0x0a, 0x11, 0x60, 0x22, 0x11, 0x68, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d10 @ cfa - 32 - 24 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x4b, 0x0a, 0x11, 0x60, 0x22, 0x11, 0x60, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d11 @ cfa - 32 - 32 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x4c, 0x0a, 0x11, 0x60, 0x22, 0x11, 0x58, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d12 @ cfa - 32 - 40 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x4d, 0x0a, 0x11, 0x60, 0x22, 0x11, 0x50, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d13 @ cfa - 32 - 48 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x4e, 0x0a, 0x11, 0x60, 0x22, 0x11, 0x48, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d14 @ cfa - 32 - 56 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x4f, 0x0a, 0x11, 0x60, 0x22, 0x11, 0x40, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d15 @ cfa - 32 - 64 * VG |
| # ASM-NEXT: .cfi_offset w19, -8 |
| # ASM-NEXT: .cfi_offset w20, -16 |
| # ASM-NEXT: .cfi_offset w21, -24 |
| # ASM-NEXT: .cfi_offset w29, -32 |
| # |
| # UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +64, DW_OP_plus, DW_OP_consts +152, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg72 DW_OP_consts -32, DW_OP_plus, DW_OP_consts -8, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg73 DW_OP_consts -32, DW_OP_plus, DW_OP_consts -16, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg74 DW_OP_consts -32, DW_OP_plus, DW_OP_consts -24, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg75 DW_OP_consts -32, DW_OP_plus, DW_OP_consts -32, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg76 DW_OP_consts -32, DW_OP_plus, DW_OP_consts -40, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg77 DW_OP_consts -32, DW_OP_plus, DW_OP_consts -48, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg78 DW_OP_consts -32, DW_OP_plus, DW_OP_consts -56, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg79 DW_OP_consts -32, DW_OP_plus, DW_OP_consts -64, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg19 -8 |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg20 -16 |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg21 -24 |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg29 -32 |
| |
| name: save_restore_sve |
| stack: |
| - { id: 0, stack-id: scalable-vector, size: 16, alignment: 16 } |
| - { id: 1, 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, -18 |
| # 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: $sp = frame-setup ADDVL_XXI $sp, -1 |
| # CHECK-NEXT: $[[TMP:x[0-9]+]] = frame-setup SUBXri $sp, 16, 0 |
| # CHECK-NEXT: $sp = ANDXri killed $[[TMP]] |
| # CHECK-COUNT-11: frame-setup CFI_INSTRUCTION |
| |
| # CHECK: $sp = frame-destroy ADDVL_XXI $fp, -18 |
| # 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 |
| # |
| # ASM-LABEL: save_restore_sve_realign: |
| # ASM: .cfi_def_cfa w29, 16 |
| # ASM-NEXT: .cfi_escape 0x10, 0x48, 0x0a, 0x11, 0x70, 0x22, 0x11, 0x78, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d8 @ cfa - 16 - 8 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x49, 0x0a, 0x11, 0x70, 0x22, 0x11, 0x70, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d9 @ cfa - 16 - 16 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x4a, 0x0a, 0x11, 0x70, 0x22, 0x11, 0x68, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d10 @ cfa - 16 - 24 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x4b, 0x0a, 0x11, 0x70, 0x22, 0x11, 0x60, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d11 @ cfa - 16 - 32 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x4c, 0x0a, 0x11, 0x70, 0x22, 0x11, 0x58, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d12 @ cfa - 16 - 40 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x4d, 0x0a, 0x11, 0x70, 0x22, 0x11, 0x50, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d13 @ cfa - 16 - 48 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x4e, 0x0a, 0x11, 0x70, 0x22, 0x11, 0x48, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d14 @ cfa - 16 - 56 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x4f, 0x0a, 0x11, 0x70, 0x22, 0x11, 0x40, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d15 @ cfa - 16 - 64 * VG |
| # ASM-NEXT: .cfi_offset w30, -8 |
| # ASM-NEXT: .cfi_offset w29, -16 |
| # |
| # UNWINDINFO: DW_CFA_def_cfa: reg29 +16 |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg72 DW_OP_consts -16, DW_OP_plus, DW_OP_consts -8, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg73 DW_OP_consts -16, DW_OP_plus, DW_OP_consts -16, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg74 DW_OP_consts -16, DW_OP_plus, DW_OP_consts -24, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg75 DW_OP_consts -16, DW_OP_plus, DW_OP_consts -32, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg76 DW_OP_consts -16, DW_OP_plus, DW_OP_consts -40, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg77 DW_OP_consts -16, DW_OP_plus, DW_OP_consts -48, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg78 DW_OP_consts -16, DW_OP_plus, DW_OP_consts -56, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg79 DW_OP_consts -16, DW_OP_plus, DW_OP_consts -64, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg30 -8 |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16 |
| name: save_restore_sve_realign |
| stack: |
| - { id: 0, stack-id: scalable-vector, size: 16, alignment: 16 } |
| - { id: 1, 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: scalable-vector, |
| # CHECK: - { id: 1, name: '', type: default, offset: -84, size: 4, alignment: 2, |
| # CHECK-NEXT: stack-id: scalable-vector, |
| # CHECK: - { id: 2, name: '', type: default, offset: -112, size: 16, alignment: 16, |
| # CHECK-NEXT: stack-id: scalable-vector, |
| # CHECK: - { id: 3, name: '', type: default, offset: -114, size: 2, alignment: 2, |
| # CHECK-NEXT: stack-id: scalable-vector, |
| # CHECK: - { id: 4, name: '', type: spill-slot, offset: -144, size: 16, alignment: 16, |
| # CHECK-NEXT: stack-id: scalable-vector, |
| # CHECK: - { id: 5, name: '', type: spill-slot, offset: -146, size: 2, alignment: 2, |
| # CHECK-NEXT: stack-id: scalable-vector, |
| # CHECK: - { id: 6, name: '', type: spill-slot, offset: -16, size: 16, alignment: 16, |
| # CHECK-NEXT: stack-id: scalable-vector, callee-saved-register: '$z8', |
| # CHECK: - { id: 7, name: '', type: spill-slot, offset: -32, size: 16, alignment: 16, |
| # CHECK-NEXT: stack-id: scalable-vector, callee-saved-register: '$z23', |
| # CHECK: - { id: 8, name: '', type: spill-slot, offset: -34, size: 2, alignment: 2, |
| # CHECK-NEXT: stack-id: scalable-vector, callee-saved-register: '$p4', |
| # CHECK: - { id: 9, name: '', type: spill-slot, offset: -36, size: 2, alignment: 2, |
| # CHECK-NEXT: stack-id: scalable-vector, 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 |
| # CHECK-COUNT-3: frame-setup CFI_INSTRUCTION |
| # ASM-LABEL: frame_layout: |
| # ASM: .cfi_escape 0x0f, 0x0d, 0x8f, 0x00, 0x11, 0x10, 0x22, 0x11, 0xd0, 0x00, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 16 + 80 * VG |
| # ASM-NEXT: .cfi_escape 0x10, 0x48, 0x0a, 0x11, 0x70, 0x22, 0x11, 0x78, 0x92, 0x2e, 0x00, 0x1e, 0x22 // $d8 @ cfa - 16 - 8 * VG |
| # ASM-NEXT: .cfi_offset w29, -16 |
| # |
| # UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +16, DW_OP_plus, DW_OP_consts +80, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_expression: reg72 DW_OP_consts -16, DW_OP_plus, DW_OP_consts -8, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus |
| # UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16 |
| name: frame_layout |
| stack: |
| - { id: 0, type: default, size: 32, alignment: 16, stack-id: scalable-vector } |
| - { id: 1, type: default, size: 4, alignment: 2, stack-id: scalable-vector } |
| - { id: 2, type: default, size: 16, alignment: 16, stack-id: scalable-vector } |
| - { id: 3, type: default, size: 2, alignment: 2, stack-id: scalable-vector } |
| - { id: 4, type: spill-slot, size: 16, alignment: 16, stack-id: scalable-vector } |
| - { id: 5, type: spill-slot, size: 2, alignment: 2, stack-id: scalable-vector } |
| body: | |
| bb.0.entry: |
| |
| ; Trigger some callee saves |
| $z8 = IMPLICIT_DEF |
| $z23 = IMPLICIT_DEF |
| $p4 = IMPLICIT_DEF |
| $p15 = IMPLICIT_DEF |
| |
| RET_ReallyLR |
| |
| --- |
| # Make sure we account for the offset between the fp and the sve area, if it exists. |
| # FIXME: Should there be an offset? |
| # CHECK-LABEL: name: fp_relative_index_with_float_save |
| # CHECK: - { id: 0, name: '', type: default, offset: -16, size: 16, alignment: 16, |
| # CHECK-NEXT: stack-id: scalable-vector |
| # CHECK: - { id: 1, name: '', type: default, offset: -64, size: 16, alignment: 32, |
| # CHECK-NEXT: stack-id: default |
| # CHECK: - { id: 2, name: '', type: spill-slot, offset: -8, size: 8, alignment: 8, |
| # CHECK-NEXT: stack-id: default, callee-saved-register: '$lr' |
| # CHECK: - { id: 3, name: '', type: spill-slot, offset: -16, size: 8, alignment: 8, |
| # CHECK-NEXT: stack-id: default, callee-saved-register: '$fp' |
| # CHECK: - { id: 4, name: '', type: spill-slot, offset: -32, size: 8, alignment: 16, |
| # CHECK-NEXT: stack-id: default, callee-saved-register: '$d8' |
| |
| # CHECK: $x8 = SUBXri $fp, 16, 0 |
| # CHECK: STR_ZXI $z0, killed $x8, -1 |
| |
| name: fp_relative_index_with_float_save |
| stack: |
| - { id: 0, stack-id: scalable-vector, size: 16, alignment: 16 } |
| - { id: 1, stack-id: default, size: 16, alignment: 32 } |
| frameInfo: |
| maxAlignment: 16 |
| isFrameAddressTaken: true |
| body: | |
| bb.0.entry: |
| liveins: $z0 |
| |
| $d8 = IMPLICIT_DEF |
| |
| STR_ZXI $z0, %stack.0, 0 |
| |
| RET_ReallyLR |
| --- |