diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -1952,12 +1952,15 @@ "non-argument/CSR objects cannot be accessed through the frame pointer"); if (isSVE) { - int64_t OffsetToSVEArea = + int64_t OffsetFromSPToSVEArea = MFI.getStackSize() - AFI->getCalleeSavedStackSize(); - StackOffset FPOffset = {ObjectOffset, MVT::nxv1i8}; + int64_t OffsetFromFPToSVEArea = + -AFI->getCalleeSaveBaseToFrameRecordOffset(); + StackOffset FPOffset = StackOffset(OffsetFromFPToSVEArea, MVT::i8) + + StackOffset(ObjectOffset, MVT::nxv1i8); StackOffset SPOffset = SVEStackSize + StackOffset(ObjectOffset, MVT::nxv1i8) + - StackOffset(OffsetToSVEArea, MVT::i8); + StackOffset(OffsetFromSPToSVEArea, MVT::i8); // Always use the FP for SVE spills if available and beneficial. if (hasFP(MF) && (SPOffset.getBytes() || diff --git a/llvm/test/CodeGen/AArch64/framelayout-sve.mir b/llvm/test/CodeGen/AArch64/framelayout-sve.mir --- a/llvm/test/CodeGen/AArch64/framelayout-sve.mir +++ b/llvm/test/CodeGen/AArch64/framelayout-sve.mir @@ -40,6 +40,7 @@ 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 } ... # +----------+ @@ -779,3 +780,37 @@ 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: sve-vec +# 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: sve-vec, 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 +---