Index: llvm/lib/Target/RISCV/RISCVFrameLowering.cpp =================================================================== --- llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -687,7 +687,10 @@ Offset += StackOffset::getFixed(FirstSPAdjustAmount); else Offset += StackOffset::getFixed(getStackSizeWithRVVPadding(MF)); - } else if (RI->hasStackRealignment(MF) && !MFI.isFixedObjectIndex(FI)) { + return Offset; + } + + if (RI->hasStackRealignment(MF) && !MFI.isFixedObjectIndex(FI)) { // If the stack was realigned, the frame pointer is set in order to allow // SP to be restored, so we need another base register to record the stack // after realignment. @@ -727,95 +730,90 @@ assert(!MFI.hasVarSizedObjects()); FrameReg = RISCV::X2; } + } else { + FrameReg = RI->getFrameRegister(MF); + } + + if (FrameReg == getFPReg(STI)) { + Offset += StackOffset::getFixed(RVFI->getVarArgsSaveSize()); + if (FI >= 0) + Offset -= StackOffset::getFixed(RVFI->getLibCallStackSize()); + // When using FP to access scalable vector objects, we need to minus + // the frame size. + // + // |--------------------------| -- <-- FP + // | callee-allocated save | | + // | area for register varargs| | + // |--------------------------| | + // | callee-saved registers | | + // |--------------------------| | MFI.getStackSize() + // | scalar local variables | | + // |--------------------------| -- (Offset of RVV objects is from here.) + // | RVV objects | + // |--------------------------| + // | VarSize objects | + // |--------------------------| <-- SP + if (MFI.getStackID(FI) == TargetStackID::ScalableVector) { + assert(!RI->hasStackRealignment(MF) && + "can't index across variable sized realign"); + // We don't expect any extra RVV alignment padding, as the stack size + // and RVV object sections should be correct aligned in their own + // right. + assert(MFI.getStackSize() == getStackSizeWithRVVPadding(MF) && + "Inconsistent stack layout"); + Offset -= StackOffset::getFixed(MFI.getStackSize()); + } + } else { + // This case handles indexing off both SP and BP. + // If indexing off SP, there must not be any var sized objects + assert(FrameReg == RISCVABI::getBPReg() || !MFI.hasVarSizedObjects()); + + // When using SP to access frame objects, we need to add RVV stack size. + // + // |--------------------------| -- <-- FP + // | callee-allocated save | | <----| + // | area for register varargs| | | + // |--------------------------| | | + // | callee-saved registers | | | + // |--------------------------| -- | + // | RVV alignment padding | | | + // | (not counted in | | | + // | MFI.getStackSize() but | | | + // | counted in | | | + // | RVFI.getRVVStackSize()) | | | + // |--------------------------| -- | + // | RVV objects | | |-- MFI.getStackSize() + // | (not counted in | | | + // | MFI.getStackSize()) | | | + // |--------------------------| -- | + // | padding before RVV | | | + // | (not counted in | | | + // | MFI.getStackSize()) | | | + // |--------------------------| -- | + // | scalar local variables | | <----' + // |--------------------------| -- <-- SP + // // The total amount of padding surrounding RVV objects is described by // RVV->getRVVPadding() and it can be zero. It allows us to align the RVV // objects to the required alignment. if (MFI.getStackID(FI) == TargetStackID::Default) { - Offset += StackOffset::getFixed(MFI.getStackSize()); - assert(FI >= 0 && "Unhandled negative frame index"); + if (MFI.isFixedObjectIndex(FI)) { + assert(!RI->hasStackRealignment(MF) && + "can't index across variable sized realign"); + Offset += StackOffset::get(getStackSizeWithRVVPadding(MF) + + RVFI->getLibCallStackSize(), + RVFI->getRVVStackSize()); + } else { + Offset += StackOffset::getFixed(MFI.getStackSize()); + } } else if (MFI.getStackID(FI) == TargetStackID::ScalableVector) { // Ensure the base of the RVV stack is correctly aligned: add on the // alignment padding. - int ScalarLocalVarSize = MFI.getStackSize() - - RVFI->getCalleeSavedStackSize() + - RVFI->getRVVPadding(); + int ScalarLocalVarSize = + MFI.getStackSize() - RVFI->getCalleeSavedStackSize() - + RVFI->getVarArgsSaveSize() + RVFI->getRVVPadding(); Offset += StackOffset::get(ScalarLocalVarSize, RVFI->getRVVStackSize()); } - } else { - FrameReg = RI->getFrameRegister(MF); - if (hasFP(MF)) { - Offset += StackOffset::getFixed(RVFI->getVarArgsSaveSize()); - if (FI >= 0) - Offset -= StackOffset::getFixed(RVFI->getLibCallStackSize()); - // When using FP to access scalable vector objects, we need to minus - // the frame size. - // - // |--------------------------| -- <-- FP - // | callee-allocated save | | - // | area for register varargs| | - // |--------------------------| | - // | callee-saved registers | | - // |--------------------------| | MFI.getStackSize() - // | scalar local variables | | - // |--------------------------| -- (Offset of RVV objects is from here.) - // | RVV objects | - // |--------------------------| - // | VarSize objects | - // |--------------------------| <-- SP - if (MFI.getStackID(FI) == TargetStackID::ScalableVector) { - // We don't expect any extra RVV alignment padding, as the stack size - // and RVV object sections should be correct aligned in their own - // right. - assert(MFI.getStackSize() == getStackSizeWithRVVPadding(MF) && - "Inconsistent stack layout"); - Offset -= StackOffset::getFixed(MFI.getStackSize()); - } - } else { - // When using SP to access frame objects, we need to add RVV stack size. - // - // |--------------------------| -- <-- FP - // | callee-allocated save | | <----| - // | area for register varargs| | | - // |--------------------------| | | - // | callee-saved registers | | | - // |--------------------------| -- | - // | RVV alignment padding | | | - // | (not counted in | | | - // | MFI.getStackSize() but | | | - // | counted in | | | - // | RVFI.getRVVStackSize()) | | | - // |--------------------------| -- | - // | RVV objects | | |-- MFI.getStackSize() - // | (not counted in | | | - // | MFI.getStackSize()) | | | - // |--------------------------| -- | - // | padding before RVV | | | - // | (not counted in | | | - // | MFI.getStackSize()) | | | - // |--------------------------| -- | - // | scalar local variables | | <----' - // |--------------------------| -- <-- SP - // - // The total amount of padding surrounding RVV objects is described by - // RVV->getRVVPadding() and it can be zero. It allows us to align the RVV - // objects to the required alignment. - if (MFI.getStackID(FI) == TargetStackID::Default) { - if (MFI.isFixedObjectIndex(FI)) { - Offset += StackOffset::get(getStackSizeWithRVVPadding(MF) + - RVFI->getLibCallStackSize(), - RVFI->getRVVStackSize()); - } else { - Offset += StackOffset::getFixed(MFI.getStackSize()); - } - } else if (MFI.getStackID(FI) == TargetStackID::ScalableVector) { - // Ensure the base of the RVV stack is correctly aligned: add on the - // alignment padding. - int ScalarLocalVarSize = - MFI.getStackSize() - RVFI->getCalleeSavedStackSize() - - RVFI->getVarArgsSaveSize() + RVFI->getRVVPadding(); - Offset += StackOffset::get(ScalarLocalVarSize, RVFI->getRVVStackSize()); - } - } } return Offset;