[llvm] [llvm][NFC]Support callee saved register info in save/restore points (PR #119358)
Elizaveta Noskova via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 27 04:02:46 PDT 2025
https://github.com/enoskova-sc updated https://github.com/llvm/llvm-project/pull/119358
>From 840ad78e534219094fd72e4e2c13ee308520ab76 Mon Sep 17 00:00:00 2001
From: Elizaveta Noskova <elizaveta.noskova at syntacore.com>
Date: Wed, 27 Aug 2025 13:29:23 +0300
Subject: [PATCH] [llvm][NFC]Support callee saved register info in save/restore
points
Now each save/restore point contain info about registers
spilled/restored in it.
---
llvm/include/llvm/CodeGen/MIRYamlMapping.h | 22 ++-
llvm/include/llvm/CodeGen/MachineFrameInfo.h | 42 ++++-
llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 20 ++-
llvm/lib/CodeGen/MIRPrinter.cpp | 39 ++++-
llvm/lib/CodeGen/MachineFrameInfo.cpp | 8 +-
llvm/lib/CodeGen/PrologEpilogInserter.cpp | 34 +++-
llvm/lib/CodeGen/ShrinkWrap.cpp | 12 +-
llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp | 6 +-
llvm/lib/Target/PowerPC/PPCFrameLowering.cpp | 5 +-
...nfo-multiple-save-restore-points-parse.mir | 4 +
...fo-save-restore-points-with-regs-parse.mir | 154 ++++++++++++++++++
.../X86/frame-info-save-restore-points.mir | 2 +
llvm/test/CodeGen/RISCV/pr53662.mir | 2 +
.../RISCV/zcmp-prolog-epilog-crash.mir | 2 +
.../CodeGen/X86/cfi-epilogue-with-return.mir | 2 +
.../X86/cfi-epilogue-without-return.mir | 2 +
llvm/tools/llvm-reduce/ReducerWorkItem.cpp | 8 +-
17 files changed, 312 insertions(+), 52 deletions(-)
create mode 100644 llvm/test/CodeGen/MIR/X86/frame-info-save-restore-points-with-regs-parse.mir
diff --git a/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
index a91c26ee1122a..f4b486063fdfa 100644
--- a/llvm/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
@@ -634,19 +634,35 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::CalledGlobal)
namespace llvm {
namespace yaml {
-// Struct representing one save/restore point in the 'savePoint'/'restorePoint'
-// list
+// Struct representing one save/restore point in the 'savePoint' /
+// 'restorePoint' list. One point consists of machine basic block name and list
+// of registers saved/restored in this basic block. In MIR it looks like:
+// savePoint:
+// - point: '%bb.1'
+// registers:
+// - '$rbx'
+// - '$r12'
+// ...
+// restorePoint:
+// - point: '%bb.1'
+// registers:
+// - '$rbx'
+// - '$r12'
+// If no register is saved/restored in the selected BB,
+// the empty list of register should be specified ( i.e. registers: [])
struct SaveRestorePointEntry {
StringValue Point;
+ std::vector<StringValue> Registers;
bool operator==(const SaveRestorePointEntry &Other) const {
- return Point == Other.Point;
+ return Point == Other.Point && Registers == Other.Registers;
}
};
template <> struct MappingTraits<SaveRestorePointEntry> {
static void mapping(IO &YamlIO, SaveRestorePointEntry &Entry) {
YamlIO.mapRequired("point", Entry.Point);
+ YamlIO.mapRequired("registers", Entry.Registers);
}
};
diff --git a/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/llvm/include/llvm/CodeGen/MachineFrameInfo.h
index e666001035deb..86094dad1c4d0 100644
--- a/llvm/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineFrameInfo.h
@@ -76,6 +76,22 @@ class CalleeSavedInfo {
bool isSpilledToReg() const { return SpilledToReg; }
};
+class SaveRestorePoints {
+public:
+ using PointsMap = DenseMap<MachineBasicBlock *, std::vector<CalleeSavedInfo>>;
+
+private:
+ PointsMap Map;
+
+public:
+ const PointsMap &get() const { return Map; }
+
+ void set(PointsMap &&CSI) { Map = std::move(CSI); }
+
+ void clear() { Map.clear(); }
+ bool empty() const { return Map.empty(); }
+};
+
/// The MachineFrameInfo class represents an abstract stack frame until
/// prolog/epilog code is inserted. This class is key to allowing stack frame
/// representation optimizations, such as frame pointer elimination. It also
@@ -333,9 +349,9 @@ class MachineFrameInfo {
bool HasTailCall = false;
/// Not empty, if shrink-wrapping found a better place for the prologue.
- SmallVector<MachineBasicBlock *, 4> SavePoints;
+ SaveRestorePoints SavePoints;
/// Not empty, if shrink-wrapping found a better place for the epilogue.
- SmallVector<MachineBasicBlock *, 4> RestorePoints;
+ SaveRestorePoints RestorePoints;
/// Size of the UnsafeStack Frame
uint64_t UnsafeStackSize = 0;
@@ -825,17 +841,25 @@ class MachineFrameInfo {
void setCalleeSavedInfoValid(bool v) { CSIValid = v; }
- ArrayRef<MachineBasicBlock *> getSavePoints() const { return SavePoints; }
- void setSavePoints(ArrayRef<MachineBasicBlock *> NewSavePoints) {
- SavePoints.assign(NewSavePoints.begin(), NewSavePoints.end());
+ const SaveRestorePoints::PointsMap &getRestorePoints() const {
+ return RestorePoints.get();
}
- ArrayRef<MachineBasicBlock *> getRestorePoints() const {
- return RestorePoints;
+
+ const SaveRestorePoints::PointsMap &getSavePoints() const {
+ return SavePoints.get();
}
- void setRestorePoints(ArrayRef<MachineBasicBlock *> NewRestorePoints) {
- RestorePoints.assign(NewRestorePoints.begin(), NewRestorePoints.end());
+
+ void setSavePoints(SaveRestorePoints::PointsMap NewSavePoints) {
+ SavePoints.set(std::move(NewSavePoints));
}
+ void setRestorePoints(SaveRestorePoints::PointsMap NewRestorePoints) {
+ RestorePoints.set(std::move(NewRestorePoints));
+ }
+
+ void clearSavePoints() { SavePoints.clear(); }
+ void clearRestorePoints() { RestorePoints.clear(); }
+
uint64_t getUnsafeStackSize() const { return UnsafeStackSize; }
void setUnsafeStackSize(uint64_t Size) { UnsafeStackSize = Size; }
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index bb70e7805e818..1319d530fede5 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -127,7 +127,7 @@ class MIRParserImpl {
bool initializeSaveRestorePoints(
PerFunctionMIParsingState &PFS,
const std::vector<yaml::SaveRestorePointEntry> &YamlSRPoints,
- SmallVectorImpl<MachineBasicBlock *> &SaveRestorePoints);
+ llvm::SaveRestorePoints::PointsMap &SaveRestorePoints);
bool initializeCallSiteInfo(PerFunctionMIParsingState &PFS,
const yaml::MachineFunction &YamlMF);
@@ -872,11 +872,11 @@ bool MIRParserImpl::initializeFrameInfo(PerFunctionMIParsingState &PFS,
MFI.setHasTailCall(YamlMFI.HasTailCall);
MFI.setCalleeSavedInfoValid(YamlMFI.IsCalleeSavedInfoValid);
MFI.setLocalFrameSize(YamlMFI.LocalFrameSize);
- SmallVector<MachineBasicBlock *, 4> SavePoints;
+ llvm::SaveRestorePoints::PointsMap SavePoints;
if (initializeSaveRestorePoints(PFS, YamlMFI.SavePoints, SavePoints))
return true;
MFI.setSavePoints(SavePoints);
- SmallVector<MachineBasicBlock *, 4> RestorePoints;
+ llvm::SaveRestorePoints::PointsMap RestorePoints;
if (initializeSaveRestorePoints(PFS, YamlMFI.RestorePoints, RestorePoints))
return true;
MFI.setRestorePoints(RestorePoints);
@@ -1098,14 +1098,22 @@ bool MIRParserImpl::initializeConstantPool(PerFunctionMIParsingState &PFS,
bool MIRParserImpl::initializeSaveRestorePoints(
PerFunctionMIParsingState &PFS,
const std::vector<yaml::SaveRestorePointEntry> &YamlSRPoints,
- SmallVectorImpl<MachineBasicBlock *> &SaveRestorePoints) {
+ llvm::SaveRestorePoints::PointsMap &SaveRestorePoints) {
+ SMDiagnostic Error;
MachineBasicBlock *MBB = nullptr;
for (const yaml::SaveRestorePointEntry &Entry : YamlSRPoints) {
if (parseMBBReference(PFS, MBB, Entry.Point.Value))
return true;
- SaveRestorePoints.push_back(MBB);
- }
+ std::vector<CalleeSavedInfo> Registers;
+ for (auto &RegStr : Entry.Registers) {
+ Register Reg;
+ if (parseNamedRegisterReference(PFS, Reg, RegStr.Value, Error))
+ return error(Error, RegStr.SourceRange);
+ Registers.push_back(CalleeSavedInfo(Reg));
+ }
+ SaveRestorePoints.try_emplace(MBB, std::move(Registers));
+ }
return false;
}
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index 7cc91925793a1..9b71f7f1fb7d4 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -149,11 +149,13 @@ static void convertMCP(yaml::MachineFunction &MF,
static void convertMJTI(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
const MachineJumpTableInfo &JTI);
static void convertMFI(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI,
- const MachineFrameInfo &MFI);
+ const MachineFrameInfo &MFI,
+ const TargetRegisterInfo *TRI);
static void
convertSRPoints(ModuleSlotTracker &MST,
std::vector<yaml::SaveRestorePointEntry> &YamlSRPoints,
- ArrayRef<MachineBasicBlock *> SaveRestorePoints);
+ const llvm::SaveRestorePoints::PointsMap &SRPoints,
+ const TargetRegisterInfo *TRI);
static void convertStackObjects(yaml::MachineFunction &YMF,
const MachineFunction &MF,
ModuleSlotTracker &MST, MFPrintState &State);
@@ -204,7 +206,8 @@ static void printMF(raw_ostream &OS, const MachineModuleInfo &MMI,
convertMRI(YamlMF, MF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
MachineModuleSlotTracker &MST = State.MST;
MST.incorporateFunction(MF.getFunction());
- convertMFI(MST, YamlMF.FrameInfo, MF.getFrameInfo());
+ convertMFI(MST, YamlMF.FrameInfo, MF.getFrameInfo(),
+ MF.getSubtarget().getRegisterInfo());
convertStackObjects(YamlMF, MF, MST, State);
convertEntryValueObjects(YamlMF, MF, MST);
convertCallSiteObjects(YamlMF, MF, MST);
@@ -339,7 +342,8 @@ static void convertMRI(yaml::MachineFunction &YamlMF, const MachineFunction &MF,
}
static void convertMFI(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI,
- const MachineFrameInfo &MFI) {
+ const MachineFrameInfo &MFI,
+ const TargetRegisterInfo *TRI) {
YamlMFI.IsFrameAddressTaken = MFI.isFrameAddressTaken();
YamlMFI.IsReturnAddressTaken = MFI.isReturnAddressTaken();
YamlMFI.HasStackMap = MFI.hasStackMap();
@@ -360,9 +364,9 @@ static void convertMFI(ModuleSlotTracker &MST, yaml::MachineFrameInfo &YamlMFI,
YamlMFI.IsCalleeSavedInfoValid = MFI.isCalleeSavedInfoValid();
YamlMFI.LocalFrameSize = MFI.getLocalFrameSize();
if (!MFI.getSavePoints().empty())
- convertSRPoints(MST, YamlMFI.SavePoints, MFI.getSavePoints());
+ convertSRPoints(MST, YamlMFI.SavePoints, MFI.getSavePoints(), TRI);
if (!MFI.getRestorePoints().empty())
- convertSRPoints(MST, YamlMFI.RestorePoints, MFI.getRestorePoints());
+ convertSRPoints(MST, YamlMFI.RestorePoints, MFI.getRestorePoints(), TRI);
}
static void convertEntryValueObjects(yaml::MachineFunction &YMF,
@@ -619,16 +623,35 @@ static void convertMCP(yaml::MachineFunction &MF,
static void
convertSRPoints(ModuleSlotTracker &MST,
std::vector<yaml::SaveRestorePointEntry> &YamlSRPoints,
- ArrayRef<MachineBasicBlock *> SRPoints) {
- for (const auto &MBB : SRPoints) {
+ const llvm::SaveRestorePoints::PointsMap &SRPoints,
+ const TargetRegisterInfo *TRI) {
+ for (const auto &[MBB, CSInfos] : SRPoints) {
SmallString<16> Str;
yaml::SaveRestorePointEntry Entry;
raw_svector_ostream StrOS(Str);
StrOS << printMBBReference(*MBB);
Entry.Point = StrOS.str().str();
Str.clear();
+ for (const CalleeSavedInfo &Info : CSInfos) {
+ if (Info.getReg()) {
+ StrOS << printReg(Info.getReg(), TRI);
+ Entry.Registers.push_back(StrOS.str().str());
+ Str.clear();
+ }
+ }
+ // Sort here needed for stable output for lit tests
+ std::sort(Entry.Registers.begin(), Entry.Registers.end(),
+ [](const yaml::StringValue &Lhs, const yaml::StringValue &Rhs) {
+ return Lhs.Value < Rhs.Value;
+ });
YamlSRPoints.push_back(Entry);
}
+ // Sort here needed for stable output for lit tests
+ std::sort(YamlSRPoints.begin(), YamlSRPoints.end(),
+ [](const yaml::SaveRestorePointEntry &Lhs,
+ const yaml::SaveRestorePointEntry &Rhs) {
+ return Lhs.Point.Value < Rhs.Point.Value;
+ });
}
static void convertMJTI(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
diff --git a/llvm/lib/CodeGen/MachineFrameInfo.cpp b/llvm/lib/CodeGen/MachineFrameInfo.cpp
index a8306b2ef2e5b..4eedc724f9167 100644
--- a/llvm/lib/CodeGen/MachineFrameInfo.cpp
+++ b/llvm/lib/CodeGen/MachineFrameInfo.cpp
@@ -249,15 +249,15 @@ void MachineFrameInfo::print(const MachineFunction &MF, raw_ostream &OS) const{
if (!SavePoints.empty()) {
OS << "save points:\n";
- for (auto &item : SavePoints)
- OS << printMBBReference(*item) << "\n";
+ for (auto &item : SavePoints.get())
+ OS << printMBBReference(*item.first) << "\n";
} else
OS << "save points are empty\n";
if (!RestorePoints.empty()) {
OS << "restore points:\n";
- for (auto &item : RestorePoints)
- OS << printMBBReference(*item) << "\n";
+ for (auto &item : RestorePoints.get())
+ OS << printMBBReference(*item.first) << "\n";
} else
OS << "restore points are empty\n";
}
diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
index 8fc0748ecc0e3..c30c5b65a50d6 100644
--- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
@@ -351,8 +351,8 @@ bool PEIImpl::run(MachineFunction &MF) {
delete RS;
SaveBlocks.clear();
RestoreBlocks.clear();
- MFI.setSavePoints({});
- MFI.setRestorePoints({});
+ MFI.clearSavePoints();
+ MFI.clearRestorePoints();
return true;
}
@@ -431,10 +431,12 @@ void PEIImpl::calculateSaveRestoreBlocks(MachineFunction &MF) {
if (!MFI.getSavePoints().empty()) {
assert(MFI.getSavePoints().size() == 1 &&
"Multiple save points are not yet supported!");
- SaveBlocks.push_back(MFI.getSavePoints().front());
+ const auto &SavePoint = *MFI.getSavePoints().begin();
+ SaveBlocks.push_back(SavePoint.first);
assert(MFI.getRestorePoints().size() == 1 &&
"Multiple restore points are not yet supported!");
- MachineBasicBlock *RestoreBlock = MFI.getRestorePoints().front();
+ const auto &RestorePoint = *MFI.getRestorePoints().begin();
+ MachineBasicBlock *RestoreBlock = RestorePoint.first;
// If RestoreBlock does not have any successor and is not a return block
// then the end point is unreachable and we do not need to insert any
// epilogue.
@@ -563,8 +565,9 @@ static void updateLiveness(MachineFunction &MF) {
assert(MFI.getSavePoints().size() < 2 &&
"Multiple save points not yet supported!");
- MachineBasicBlock *Save =
- MFI.getSavePoints().empty() ? nullptr : MFI.getSavePoints().front();
+ MachineBasicBlock *Save = MFI.getSavePoints().empty()
+ ? nullptr
+ : (*MFI.getSavePoints().begin()).first;
if (!Save)
Save = Entry;
@@ -577,8 +580,9 @@ static void updateLiveness(MachineFunction &MF) {
assert(MFI.getRestorePoints().size() < 2 &&
"Multiple restore points not yet supported!");
- MachineBasicBlock *Restore =
- MFI.getRestorePoints().empty() ? nullptr : MFI.getRestorePoints().front();
+ MachineBasicBlock *Restore = MFI.getRestorePoints().empty()
+ ? nullptr
+ : (*MFI.getRestorePoints().begin()).first;
if (Restore)
// By construction Restore cannot be visited, otherwise it
// means there exists a path to Restore that does not go
@@ -687,6 +691,20 @@ void PEIImpl::spillCalleeSavedRegs(MachineFunction &MF) {
MFI.setCalleeSavedInfoValid(true);
std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
+
+ // Fill SavePoints and RestorePoints with CalleeSavedRegisters
+ if (!MFI.getSavePoints().empty()) {
+ SaveRestorePoints::PointsMap SaveRestorePts;
+ for (const auto &SavePoint : MFI.getSavePoints())
+ SaveRestorePts.insert({SavePoint.first, CSI});
+ MFI.setSavePoints(std::move(SaveRestorePts));
+
+ SaveRestorePts.clear();
+ for (const auto &RestorePoint : MFI.getRestorePoints())
+ SaveRestorePts.insert({RestorePoint.first, CSI});
+ MFI.setRestorePoints(std::move(SaveRestorePts));
+ }
+
if (!CSI.empty()) {
if (!MFI.hasCalls())
NumLeafFuncWithSpills++;
diff --git a/llvm/lib/CodeGen/ShrinkWrap.cpp b/llvm/lib/CodeGen/ShrinkWrap.cpp
index 938f2d756bc87..7d6aaedb4de4d 100644
--- a/llvm/lib/CodeGen/ShrinkWrap.cpp
+++ b/llvm/lib/CodeGen/ShrinkWrap.cpp
@@ -967,12 +967,12 @@ bool ShrinkWrapImpl::run(MachineFunction &MF) {
<< "\nRestore: " << printMBBReference(*Restore) << '\n');
MachineFrameInfo &MFI = MF.getFrameInfo();
- SmallVector<MachineBasicBlock *, 4> SavePoints;
- SmallVector<MachineBasicBlock *, 4> RestorePoints;
- if (Save) {
- SavePoints.push_back(Save);
- RestorePoints.push_back(Restore);
- }
+
+ // List of CalleeSavedInfo for registers will be added during prologepilog
+ // pass
+ SaveRestorePoints::PointsMap SavePoints({{Save, {}}});
+ SaveRestorePoints::PointsMap RestorePoints({{Restore, {}}});
+
MFI.setSavePoints(SavePoints);
MFI.setRestorePoints(RestorePoints);
++NumCandidates;
diff --git a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
index 1a91bbd433553..40eeeb8a8630d 100644
--- a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
+++ b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
@@ -213,10 +213,12 @@ void SILowerSGPRSpills::calculateSaveRestoreBlocks(MachineFunction &MF) {
if (!MFI.getSavePoints().empty()) {
assert(MFI.getSavePoints().size() == 1 &&
"Multiple save points not yet supported!");
- SaveBlocks.push_back(MFI.getSavePoints().front());
+ const auto &SavePoint = *MFI.getSavePoints().begin();
+ SaveBlocks.push_back(SavePoint.first);
assert(MFI.getRestorePoints().size() == 1 &&
"Multiple restore points not yet supported!");
- MachineBasicBlock *RestoreBlock = MFI.getRestorePoints().front();
+ const auto &RestorePoint = *MFI.getRestorePoints().begin();
+ MachineBasicBlock *RestoreBlock = RestorePoint.first;
// If RestoreBlock does not have any successor and is not a return block
// then the end point is unreachable and we do not need to insert any
// epilogue.
diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
index 2ad3ed21732ed..6300ace338db7 100644
--- a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
@@ -2081,9 +2081,10 @@ void PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
if (!MFI.getSavePoints().empty() && MFI.hasTailCall()) {
assert(MFI.getRestorePoints().size() < 2 &&
"MFI can't contain multiple restore points!");
- MachineBasicBlock *RestoreBlock = MFI.getRestorePoints().front();
+ const auto &RestorePoint = *MFI.getRestorePoints().begin();
+ MachineBasicBlock *RestoreBlock = RestorePoint.first;
for (MachineBasicBlock &MBB : MF) {
- if (MBB.isReturnBlock() && (&MBB) != RestoreBlock)
+ if (MBB.isReturnBlock() && (!MFI.getRestorePoints().contains(&MBB)))
createTailCallBranchInstr(MBB);
}
}
diff --git a/llvm/test/CodeGen/MIR/X86/frame-info-multiple-save-restore-points-parse.mir b/llvm/test/CodeGen/MIR/X86/frame-info-multiple-save-restore-points-parse.mir
index 4c60ccd573595..f5ea96e3a7507 100644
--- a/llvm/test/CodeGen/MIR/X86/frame-info-multiple-save-restore-points-parse.mir
+++ b/llvm/test/CodeGen/MIR/X86/frame-info-multiple-save-restore-points-parse.mir
@@ -42,10 +42,14 @@ frameInfo:
hasCalls: true
savePoint:
- point: '%bb.1'
+ registers: []
- point: '%bb.2'
+ registers: []
restorePoint:
- point: '%bb.2'
+ registers: []
- point: '%bb.3'
+ registers: []
stack:
- { id: 0, name: tmp, offset: 0, size: 4, alignment: 4 }
body: |
diff --git a/llvm/test/CodeGen/MIR/X86/frame-info-save-restore-points-with-regs-parse.mir b/llvm/test/CodeGen/MIR/X86/frame-info-save-restore-points-with-regs-parse.mir
new file mode 100644
index 0000000000000..d23f2f7bd585e
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/X86/frame-info-save-restore-points-with-regs-parse.mir
@@ -0,0 +1,154 @@
+# RUN: llc -run-pass none -o - %s | FileCheck %s
+
+--- |
+ define ptr @foo(ptr %ptr, i64 %p2, i64 %p3, i64 %p4, i64 %p5, i64 %p6) {
+ entry:
+ %tobool.not = icmp eq ptr %ptr, null
+ br i1 %tobool.not, label %if.then, label %if.end
+
+ if.then: ; preds = %entry
+ %call = tail call ptr @bar(ptr %ptr, i64 %p2, i64 %p3, i64 %p4, i64 %p5, i64 %p6)
+ br label %if.end
+
+ if.end: ; preds = %if.then, %entry
+ %ptr.addr.0 = phi ptr [ %call, %if.then ], [ %ptr, %entry ]
+ %incdec.ptr = getelementptr inbounds i8, ptr %ptr.addr.0, i64 1
+ %call2 = tail call ptr @qux(ptr %incdec.ptr, i64 %p2, i64 %p3, i64 %p4, i64 %p5, i64 %p6)
+ ret ptr %call2
+ }
+
+ declare ptr @bar(ptr, i64, i64, i64, i64, i64)
+
+ declare ptr @qux(ptr, i64, i64, i64, i64, i64)
+...
+---
+name: foo
+alignment: 16
+exposesReturnsTwice: false
+legalized: false
+regBankSelected: false
+selected: false
+failedISel: false
+tracksRegLiveness: true
+hasWinCFI: false
+noPhis: true
+isSSA: false
+noVRegs: true
+hasFakeUses: false
+callsEHReturn: false
+callsUnwindInit: false
+hasEHContTarget: false
+hasEHScopes: false
+hasEHFunclets: false
+isOutlined: false
+debugInstrRef: true
+failsVerification: false
+tracksDebugUserValues: true
+registers: []
+liveins:
+ - { reg: '$rdi', virtual-reg: '' }
+ - { reg: '$rsi', virtual-reg: '' }
+ - { reg: '$rdx', virtual-reg: '' }
+ - { reg: '$rcx', virtual-reg: '' }
+ - { reg: '$r8', virtual-reg: '' }
+ - { reg: '$r9', virtual-reg: '' }
+frameInfo:
+ isFrameAddressTaken: false
+ isReturnAddressTaken: false
+ hasStackMap: false
+ hasPatchPoint: false
+ stackSize: 0
+ offsetAdjustment: 0
+ maxAlignment: 1
+ adjustsStack: true
+ hasCalls: true
+ stackProtector: ''
+ functionContext: ''
+ maxCallFrameSize: 4294967295
+ cvBytesOfCalleeSavedRegisters: 0
+ hasOpaqueSPAdjustment: false
+ hasVAStart: false
+ hasMustTailInVarArgFunc: false
+ hasTailCall: true
+ isCalleeSavedInfoValid: false
+ localFrameSize: 0
+# CHECK: savePoint:
+# CHECK-NEXT: - point: '%bb.2'
+# CHECK-NEXT: registers:
+# CHECK-NEXT: - '$r12'
+# CHECK-NEXT: - '$r13'
+# CHECK-NEXT: - '$r14'
+# CHECK-NEXT: - '$r15'
+# CHECK-NEXT: - '$rbx'
+# CHECK: restorePoint:
+# CHECK-NEXT: - point: '%bb.2'
+# CHECK-NEXT: registers:
+# CHECK-NEXT: - '$r12'
+# CHECK-NEXT: - '$r13'
+# CHECK-NEXT: - '$r14'
+# CHECK-NEXT: - '$r15'
+# CHECK-NEXT: - '$rbx'
+ savePoint:
+ - point: '%bb.1'
+ registers:
+ - '$rbx'
+ - '$r12'
+ - '$r13'
+ - '$r14'
+ - '$r15'
+ restorePoint:
+ - point: '%bb.1'
+ registers:
+ - '$rbx'
+ - '$r12'
+ - '$r13'
+ - '$r14'
+ - '$r15'
+fixedStack: []
+stack: []
+entry_values: []
+callSites: []
+debugValueSubstitutions: []
+constants: []
+machineFunctionInfo:
+ amxProgModel: None
+body: |
+ bb.0.entry:
+ successors: %bb.1(0x30000000), %bb.3(0x50000000)
+ liveins: $rcx, $rdi, $rdx, $rsi, $r8, $r9
+
+ TEST64rr renamable $rdi, renamable $rdi, implicit-def $eflags
+ JCC_1 %bb.1, 4, implicit killed $eflags
+
+ bb.3:
+ successors: %bb.2(0x80000000)
+ liveins: $rcx, $rdi, $rdx, $rsi, $r8, $r9
+
+ JMP_1 %bb.2
+
+ bb.1.if.then:
+ successors: %bb.2(0x80000000)
+ liveins: $rcx, $rdi, $rdx, $rsi, $r8, $r9
+
+ ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ renamable $rbx = COPY renamable $rsi
+ renamable $r14 = COPY renamable $rdx
+ renamable $r15 = COPY renamable $rcx
+ renamable $r12 = COPY renamable $r8
+ renamable $r13 = COPY renamable $r9
+ CALL64pcrel32 target-flags(x86-plt) @bar, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit $rdx, implicit $rcx, implicit $r8, implicit $r9, implicit-def $rsp, implicit-def $ssp, implicit-def $rax
+ renamable $rsi = COPY killed renamable $rbx
+ renamable $rdx = COPY killed renamable $r14
+ renamable $rcx = COPY killed renamable $r15
+ renamable $r8 = COPY killed renamable $r12
+ renamable $r9 = COPY killed renamable $r13
+ ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ renamable $rdi = COPY killed $rax
+
+ bb.2.if.end:
+ liveins: $rcx, $rdi, $rdx, $rsi, $r8, $r9
+
+ renamable $rdi = nuw INC64r killed renamable $rdi, implicit-def dead $eflags
+ TCRETURNdi64 target-flags(x86-plt) @qux, 0, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit $rdx, implicit $rcx, implicit $r8, implicit $r9
+...
+
diff --git a/llvm/test/CodeGen/MIR/X86/frame-info-save-restore-points.mir b/llvm/test/CodeGen/MIR/X86/frame-info-save-restore-points.mir
index 6357c5a30da89..d3573035949b8 100644
--- a/llvm/test/CodeGen/MIR/X86/frame-info-save-restore-points.mir
+++ b/llvm/test/CodeGen/MIR/X86/frame-info-save-restore-points.mir
@@ -40,8 +40,10 @@ frameInfo:
hasCalls: true
savePoint:
- point: '%bb.2'
+ registers: []
restorePoint:
- point: '%bb.2'
+ registers: []
stack:
- { id: 0, name: tmp, offset: 0, size: 4, alignment: 4 }
body: |
diff --git a/llvm/test/CodeGen/RISCV/pr53662.mir b/llvm/test/CodeGen/RISCV/pr53662.mir
index dccad40368111..d859984629086 100644
--- a/llvm/test/CodeGen/RISCV/pr53662.mir
+++ b/llvm/test/CodeGen/RISCV/pr53662.mir
@@ -12,8 +12,10 @@ name: b
frameInfo:
savePoint:
- point: '%bb.0'
+ registers: []
restorePoint:
- point: '%bb.1'
+ registers: []
body: |
; CHECK-LABEL: name: b
; CHECK: bb.0:
diff --git a/llvm/test/CodeGen/RISCV/zcmp-prolog-epilog-crash.mir b/llvm/test/CodeGen/RISCV/zcmp-prolog-epilog-crash.mir
index 979b8a4e17d5a..f8cc8f4b86c8e 100644
--- a/llvm/test/CodeGen/RISCV/zcmp-prolog-epilog-crash.mir
+++ b/llvm/test/CodeGen/RISCV/zcmp-prolog-epilog-crash.mir
@@ -40,8 +40,10 @@ frameInfo:
localFrameSize: 32
savePoint:
- point: '%bb.2'
+ registers: []
restorePoint:
- point: '%bb.2'
+ registers: []
stack:
- { id: 0, size: 32, alignment: 1, local-offset: -32 }
machineFunctionInfo:
diff --git a/llvm/test/CodeGen/X86/cfi-epilogue-with-return.mir b/llvm/test/CodeGen/X86/cfi-epilogue-with-return.mir
index 4f80f4f87dd0d..175e6970f4cba 100644
--- a/llvm/test/CodeGen/X86/cfi-epilogue-with-return.mir
+++ b/llvm/test/CodeGen/X86/cfi-epilogue-with-return.mir
@@ -23,8 +23,10 @@ frameInfo:
hasCalls: true
savePoint:
- point: '%bb.1'
+ registers: []
restorePoint:
- point: '%bb.1'
+ registers: []
machineFunctionInfo: {}
body: |
bb.0:
diff --git a/llvm/test/CodeGen/X86/cfi-epilogue-without-return.mir b/llvm/test/CodeGen/X86/cfi-epilogue-without-return.mir
index 38c081c94ab91..eed33f81d802c 100644
--- a/llvm/test/CodeGen/X86/cfi-epilogue-without-return.mir
+++ b/llvm/test/CodeGen/X86/cfi-epilogue-without-return.mir
@@ -30,8 +30,10 @@ frameInfo:
hasCalls: true
savePoint:
- point: '%bb.1'
+ registers: []
restorePoint:
- point: '%bb.1'
+ registers: []
machineFunctionInfo: {}
body: |
bb.0:
diff --git a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
index b1138ef9d5289..cb1b6b007a621 100644
--- a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
+++ b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
@@ -62,12 +62,12 @@ static cl::opt<bool> TmpFilesAsBitcode(
cl::desc("Always write temporary files as bitcode instead of textual IR"),
cl::init(false), cl::cat(LLVMReduceOptions));
-static SmallVector<MachineBasicBlock *> constructSaveRestorePoints(
- ArrayRef<MachineBasicBlock *> SRPoints,
+static SaveRestorePoints::PointsMap constructSaveRestorePoints(
+ const SaveRestorePoints::PointsMap &SRPoints,
const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &BBMap) {
- SmallVector<MachineBasicBlock *> Pts;
+ SaveRestorePoints::PointsMap Pts{};
for (auto &Src : SRPoints)
- Pts.push_back(BBMap.find(Src)->second);
+ Pts.insert({BBMap.find(Src.first)->second, Src.second});
return Pts;
}
More information about the llvm-commits
mailing list