Skip to content

Commit 6983c12

Browse files
committed
Fixups
1 parent bdaf58f commit 6983c12

File tree

2 files changed

+33
-29
lines changed

2 files changed

+33
-29
lines changed

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -546,12 +546,25 @@ bool AArch64FrameLowering::hasFPImpl(const MachineFunction &MF) const {
546546
MFI.hasStackMap() || MFI.hasPatchPoint() ||
547547
RegInfo->hasStackRealignment(MF))
548548
return true;
549-
// If we have streaming mode changes and SVE registers on the stack we need a
550-
// FP. This is as the stack size may depend on the VG at entry to the
551-
// function, which is saved before the SVE area (so unrecoverable without a
552-
// FP). Similar for locally streaming functions, but it is because we use
553-
// ADDSVL to setup the SVE stack (which might not match VG, even without
554-
// streaming-mode changes).
549+
550+
// If we:
551+
//
552+
// 1. Have streaming mode changes
553+
// OR:
554+
// 2. Have a streaming body with SVE stack objects
555+
//
556+
// Then the value of VG restored when unwinding to this function may not match
557+
// the value of VG used to set up the stack.
558+
//
559+
// This is a problem as the CFA can be described with an expression of the
560+
// form: CFA = SP + NumBytes + VG * NumScalableBytes.
561+
//
562+
// If the value of VG used in that expression does not match the value used to
563+
// set up the stack, an incorrect address for the CFA will be computed, and
564+
// unwinding will fail.
565+
//
566+
// We work around this issue by ensuring the frame-pointer can describe the
567+
// CFA in either of these cases.
555568
if (AFI.needsDwarfUnwindInfo(MF) &&
556569
((requiresSaveVG(MF) || AFI.getSMEFnAttrs().hasStreamingBody()) &&
557570
(!AFI.hasCalculatedStackSizeSVE() || AFI.getStackSizeSVE() > 0)))
@@ -1498,7 +1511,7 @@ bool isVGInstruction(MachineBasicBlock::iterator MBBI,
14981511
if (Opc == AArch64::BL)
14991512
return matchLibcall(TLI, MBBI->getOperand(0), RTLIB::SMEABI_GET_CURRENT_VG);
15001513

1501-
return Opc == AArch64::ORRXrr;
1514+
return Opc == TargetOpcode::COPY;
15021515
}
15031516

15041517
// Convert callee-save register save/restore instruction to do stack pointer
@@ -3548,10 +3561,8 @@ bool AArch64FrameLowering::spillCalleeSavedRegisters(
35483561
unsigned X0Scratch = AArch64::NoRegister;
35493562
auto RestoreX0 = make_scope_exit([&] {
35503563
if (X0Scratch != AArch64::NoRegister)
3551-
BuildMI(MBB, MI, DL, TII.get(AArch64::ORRXrr), AArch64::X0)
3552-
.addReg(AArch64::XZR)
3553-
.addReg(X0Scratch, RegState::Undef)
3554-
.addReg(X0Scratch, RegState::Implicit)
3564+
BuildMI(MBB, MI, DL, TII.get(TargetOpcode::COPY), AArch64::X0)
3565+
.addReg(X0Scratch)
35553566
.setMIFlag(MachineInstr::FrameSetup);
35563567
});
35573568

@@ -3570,15 +3581,12 @@ bool AArch64FrameLowering::spillCalleeSavedRegisters(
35703581
[&STI](const MachineBasicBlock::RegisterMaskPair &LiveIn) {
35713582
return STI.getRegisterInfo()->isSuperOrSubRegisterEq(
35723583
AArch64::X0, LiveIn.PhysReg);
3573-
}))
3584+
})) {
35743585
X0Scratch = Reg1;
3575-
3576-
if (X0Scratch != AArch64::NoRegister)
3577-
BuildMI(MBB, MI, DL, TII.get(AArch64::ORRXrr), Reg1)
3578-
.addReg(AArch64::XZR)
3579-
.addReg(AArch64::X0, RegState::Undef)
3580-
.addReg(AArch64::X0, RegState::Implicit)
3586+
BuildMI(MBB, MI, DL, TII.get(TargetOpcode::COPY), X0Scratch)
3587+
.addReg(AArch64::X0)
35813588
.setMIFlag(MachineInstr::FrameSetup);
3589+
}
35823590

35833591
RTLIB::Libcall LC = RTLIB::SMEABI_GET_CURRENT_VG;
35843592
const uint32_t *RegMask =
@@ -4214,16 +4222,11 @@ bool AArch64FrameLowering::assignCalleeSavedSpillSlots(
42144222
// Insert VG into the list of CSRs, immediately before LR if saved.
42154223
if (requiresSaveVG(MF)) {
42164224
CalleeSavedInfo VGInfo(AArch64::VG);
4217-
4218-
bool InsertedBeforeLR = false;
4219-
for (unsigned I = 0; I < CSI.size(); I++)
4220-
if (CSI[I].getReg() == AArch64::LR) {
4221-
InsertedBeforeLR = true;
4222-
CSI.insert(CSI.begin() + I, VGInfo);
4223-
break;
4224-
}
4225-
4226-
if (!InsertedBeforeLR)
4225+
auto It =
4226+
find_if(CSI, [](auto &Info) { return Info.getReg() == AArch64::LR; });
4227+
if (It != CSI.end())
4228+
CSI.insert(It, VGInfo);
4229+
else
42274230
CSI.push_back(VGInfo);
42284231
}
42294232

llvm/lib/Target/AArch64/AArch64InstrInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6002,12 +6002,13 @@ llvm::createCFAOffset(const TargetRegisterInfo &TRI, unsigned Reg,
60026002
assert(NumVGScaledBytes && "Expected scalable offset");
60036003
SmallString<64> OffsetExpr;
60046004
// + VG * NumVGScaledBytes
6005-
StringRef VGRegScale("* VG");
6005+
StringRef VGRegScale;
60066006
if (IncomingVGOffsetFromDefCFA) {
60076007
appendLoadRegExpr(OffsetExpr, *IncomingVGOffsetFromDefCFA);
60086008
VGRegScale = "* IncomingVG";
60096009
} else {
60106010
appendReadRegExpr(OffsetExpr, TRI.getDwarfRegNum(AArch64::VG, true));
6011+
VGRegScale = "* VG";
60116012
}
60126013
appendConstantExpr(OffsetExpr, NumVGScaledBytes, dwarf::DW_OP_mul);
60136014
appendOffsetComment(NumVGScaledBytes, Comment, VGRegScale);

0 commit comments

Comments
 (0)