Skip to content

[AArch64][SVE] Avoid using the SVE stack size before it is determined (hopefully mostly a NFC) #147561

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,26 @@ static Register findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB,
bool HasCall = false);
static bool requiresSaveVG(const MachineFunction &MF);

// Conservatively, returns true if the function is likely to have an SVE vectors
// on the stack. This function is safe to be called before callee-saves or
// object offsets have been determined.
static bool isLikelyToHaveSVEStack(MachineFunction &MF) {
auto *AFI = MF.getInfo<AArch64FunctionInfo>();
if (AFI->isSVECC())
return true;

if (AFI->hasCalculatedStackSizeSVE())
return bool(getSVEStackSize(MF));

const MachineFrameInfo &MFI = MF.getFrameInfo();
for (int FI = MFI.getObjectIndexBegin(); FI < MFI.getObjectIndexEnd(); FI++) {
if (MFI.getStackID(FI) == TargetStackID::ScalableVector)
return true;
}

return false;
}

/// Returns true if a homogeneous prolog or epilog code can be emitted
/// for the size optimization. If possible, a frame helper call is injected.
/// When Exit block is given, this check is for epilog.
Expand All @@ -350,8 +370,9 @@ bool AArch64FrameLowering::homogeneousPrologEpilog(
// TODO: Window is supported yet.
if (needsWinCFI(MF))
return false;

// TODO: SVE is not supported yet.
if (getSVEStackSize(MF))
if (isLikelyToHaveSVEStack(MF))
return false;

// Bail on stack adjustment needed on return for simplicity.
Expand Down Expand Up @@ -2997,7 +3018,7 @@ static bool produceCompactUnwindFrame(MachineFunction &MF) {
!(Subtarget.getTargetLowering()->supportSwiftError() &&
Attrs.hasAttrSomewhere(Attribute::SwiftError)) &&
MF.getFunction().getCallingConv() != CallingConv::SwiftTail &&
!requiresSaveVG(MF) && AFI->getSVECalleeSavedStackSize() == 0;
!requiresSaveVG(MF) && !AFI->isSVECC();
}

static bool invalidateWindowsRegisterPairing(unsigned Reg1, unsigned Reg2,
Expand Down
7 changes: 6 additions & 1 deletion llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ using namespace llvm;

yaml::AArch64FunctionInfo::AArch64FunctionInfo(
const llvm::AArch64FunctionInfo &MFI)
: HasRedZone(MFI.hasRedZone()) {}
: HasRedZone(MFI.hasRedZone()),
StackSizeSVE(MFI.hasCalculatedStackSizeSVE()
? std::optional<uint64_t>(MFI.getStackSizeSVE())
: std::nullopt) {}

void yaml::AArch64FunctionInfo::mappingImpl(yaml::IO &YamlIO) {
MappingTraits<AArch64FunctionInfo>::mapping(YamlIO, *this);
Expand All @@ -35,6 +38,8 @@ void AArch64FunctionInfo::initializeBaseYamlFields(
const yaml::AArch64FunctionInfo &YamlMFI) {
if (YamlMFI.HasRedZone)
HasRedZone = YamlMFI.HasRedZone;
if (YamlMFI.StackSizeSVE)
setStackSizeSVE(*YamlMFI.StackSizeSVE);
}

static std::pair<bool, bool> GetSignReturnAddress(const Function &F) {
Expand Down
11 changes: 10 additions & 1 deletion llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
unsigned CalleeSavedStackSize = 0;
unsigned SVECalleeSavedStackSize = 0;
bool HasCalleeSavedStackSize = false;
bool HasSVECalleeSavedStackSize = false;

/// Number of TLS accesses using the special (combinable)
/// _TLS_MODULE_BASE_ symbol.
Expand Down Expand Up @@ -306,7 +307,10 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
StackSizeSVE = S;
}

uint64_t getStackSizeSVE() const { return StackSizeSVE; }
uint64_t getStackSizeSVE() const {
assert(hasCalculatedStackSizeSVE());
return StackSizeSVE;
}

bool hasStackFrame() const { return HasStackFrame; }
void setHasStackFrame(bool s) { HasStackFrame = s; }
Expand Down Expand Up @@ -400,8 +404,11 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
// Saves the CalleeSavedStackSize for SVE vectors in 'scalable bytes'
void setSVECalleeSavedStackSize(unsigned Size) {
SVECalleeSavedStackSize = Size;
HasSVECalleeSavedStackSize = true;
}
unsigned getSVECalleeSavedStackSize() const {
assert(HasSVECalleeSavedStackSize &&
"SVECalleeSavedStackSize has not been calculated");
return SVECalleeSavedStackSize;
}

Expand Down Expand Up @@ -592,6 +599,7 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
namespace yaml {
struct AArch64FunctionInfo final : public yaml::MachineFunctionInfo {
std::optional<bool> HasRedZone;
std::optional<uint64_t> StackSizeSVE;

AArch64FunctionInfo() = default;
AArch64FunctionInfo(const llvm::AArch64FunctionInfo &MFI);
Expand All @@ -603,6 +611,7 @@ struct AArch64FunctionInfo final : public yaml::MachineFunctionInfo {
template <> struct MappingTraits<AArch64FunctionInfo> {
static void mapping(IO &YamlIO, AArch64FunctionInfo &MFI) {
YamlIO.mapOptional("hasRedZone", MFI.HasRedZone);
YamlIO.mapOptional("stackSizeSVE", MFI.StackSizeSVE);
}
};

Expand Down
2 changes: 2 additions & 0 deletions llvm/test/DebugInfo/AArch64/asan-stack-vars.mir
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ frameInfo:
stackProtector: '%stack.0.StackGuardSlot'
maxCallFrameSize: 0
localFrameSize: 144
machineFunctionInfo:
stackSizeSVE: 0
stack:
- { id: 0, name: StackGuardSlot, offset: -40, size: 8, alignment: 8,
stack-id: default, local-offset: -8 }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ frameInfo:
adjustsStack: true
hasCalls: true
maxCallFrameSize: 0
machineFunctionInfo:
stackSizeSVE: 0
stack:
- { id: 0, type: spill-slot, offset: -20, size: 4, alignment: 4, stack-id: default }
- { id: 1, type: spill-slot, offset: -8, size: 8, alignment: 8, stack-id: default,
Expand Down
Loading