[llvm-branch-commits] [llvm] [WIP] Users/ppenzin/ra saverestore early cfi (PR #170610)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Dec 3 22:24:17 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Petr Penzin (ppenzin)
<details>
<summary>Changes</summary>
Add ability to emit CFIs if the registers were saved / restored before prolog / epilog insertion.
This has been split out from https://github.com/mgudim/llvm-project/tree/save_csr_in_ra3, and is PR 4 out of 5.
Co-authored-by: Mikhail Gudim <mgudim@<!-- -->ventanamicro.com>
---
Full diff: https://github.com/llvm/llvm-project/pull/170610.diff
8 Files Affected:
- (modified) llvm/include/llvm/CodeGen/TargetFrameLowering.h (+17-10)
- (modified) llvm/lib/CodeGen/PrologEpilogInserter.cpp (+15-3)
- (modified) llvm/lib/Target/RISCV/RISCVFrameLowering.cpp (+149)
- (modified) llvm/lib/Target/RISCV/RISCVFrameLowering.h (+2)
- (modified) llvm/lib/Target/RISCV/RISCVSubtarget.cpp (+7-8)
- (modified) llvm/test/CodeGen/RISCV/O0-pipeline.ll (+1)
- (modified) llvm/test/CodeGen/RISCV/O3-pipeline.ll (+1)
- (added) llvm/test/CodeGen/RISCV/emit-early-cfis.mir (+108)
``````````diff
diff --git a/llvm/include/llvm/CodeGen/TargetFrameLowering.h b/llvm/include/llvm/CodeGen/TargetFrameLowering.h
index c04cd33b3377a..fe3ebcd13b2bc 100644
--- a/llvm/include/llvm/CodeGen/TargetFrameLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetFrameLowering.h
@@ -25,16 +25,17 @@ namespace llvm {
class CalleeSavedInfo;
class MachineFunction;
class RegScavenger;
-
-namespace TargetStackID {
-enum Value {
- Default = 0,
- SGPRSpill = 1,
- ScalableVector = 2,
- WasmLocal = 3,
- ScalablePredicateVector = 4,
- NoAlloc = 255
-};
+ class ReachingDefInfo;
+
+ namespace TargetStackID {
+ enum Value {
+ Default = 0,
+ SGPRSpill = 1,
+ ScalableVector = 2,
+ WasmLocal = 3,
+ ScalablePredicateVector = 4,
+ NoAlloc = 255
+ };
}
/// Information about stack frame layout on the target. It holds the direction
@@ -212,6 +213,12 @@ class LLVM_ABI TargetFrameLowering {
/// for noreturn nounwind functions.
virtual bool enableCalleeSaveSkip(const MachineFunction &MF) const;
+ /// If savesCSRsEarly is true, we don't really know where the CSRs are
+ /// saved. This function calculates where each CSR is at every point in the
+ /// function and inserts necessary CFIs. It has to run before frame indicies
+ /// are resolved.
+ virtual void emitCFIsEarly(MachineFunction &MF, ReachingDefInfo &RDA) const {}
+
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
/// the function.
virtual void emitPrologue(MachineFunction &MF,
diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
index 2639edcfed0a2..b97c5cd4e98d5 100644
--- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
@@ -36,6 +36,7 @@
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PEI.h"
+#include "llvm/CodeGen/ReachingDefAnalysis.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
@@ -79,6 +80,7 @@ namespace {
class PEIImpl {
RegScavenger *RS = nullptr;
+ ReachingDefInfo &RDI;
// MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee saved
// stack frame indexes.
@@ -125,7 +127,8 @@ class PEIImpl {
void insertZeroCallUsedRegs(MachineFunction &MF);
public:
- PEIImpl(MachineOptimizationRemarkEmitter *ORE) : ORE(ORE) {}
+ PEIImpl(ReachingDefInfo &RDI, MachineOptimizationRemarkEmitter *ORE)
+ : RDI(RDI), ORE(ORE) {}
bool run(MachineFunction &MF);
};
@@ -155,6 +158,7 @@ INITIALIZE_PASS_BEGIN(PEILegacy, DEBUG_TYPE, "Prologue/Epilogue Insertion",
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
+INITIALIZE_PASS_DEPENDENCY(ReachingDefInfoWrapperPass)
INITIALIZE_PASS_END(PEILegacy, DEBUG_TYPE,
"Prologue/Epilogue Insertion & Frame Finalization", false,
false)
@@ -171,6 +175,7 @@ void PEILegacy::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addPreserved<MachineLoopInfoWrapperPass>();
AU.addPreserved<MachineDominatorTreeWrapperPass>();
AU.addRequired<MachineOptimizationRemarkEmitterPass>();
+ AU.addRequired<ReachingDefInfoWrapperPass>();
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -361,7 +366,8 @@ bool PEIImpl::run(MachineFunction &MF) {
bool PEILegacy::runOnMachineFunction(MachineFunction &MF) {
MachineOptimizationRemarkEmitter *ORE =
&getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
- return PEIImpl(ORE).run(MF);
+ auto &RDI = getAnalysis<ReachingDefInfoWrapperPass>().getRDI();
+ return PEIImpl(RDI, ORE).run(MF);
}
PreservedAnalyses
@@ -369,7 +375,8 @@ PrologEpilogInserterPass::run(MachineFunction &MF,
MachineFunctionAnalysisManager &MFAM) {
MachineOptimizationRemarkEmitter &ORE =
MFAM.getResult<MachineOptimizationRemarkEmitterAnalysis>(MF);
- if (!PEIImpl(&ORE).run(MF))
+ auto &RDI = MFAM.getResult<ReachingDefAnalysis>(MF);
+ if (!PEIImpl(RDI, &ORE).run(MF))
return PreservedAnalyses::all();
return getMachineFunctionPassPreservedAnalyses()
@@ -1188,6 +1195,11 @@ void PEIImpl::calculateFrameObjectOffsets(MachineFunction &MF) {
void PEIImpl::insertPrologEpilogCode(MachineFunction &MF) {
const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
+ if (MF.getSubtarget().savesCSRsEarly()) {
+ RDI.reset();
+ TFI.emitCFIsEarly(MF, RDI);
+ }
+
// Add prologue to the function...
for (MachineBasicBlock *SaveBlock : SaveBlocks)
TFI.emitPrologue(MF, *SaveBlock);
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index f780375454b2a..17f4d0beabe31 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -14,6 +14,7 @@
#include "MCTargetDesc/RISCVBaseInfo.h"
#include "RISCVMachineFunctionInfo.h"
#include "RISCVSubtarget.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/CFIInstBuilder.h"
#include "llvm/CodeGen/LivePhysRegs.h"
@@ -21,6 +22,7 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/ReachingDefAnalysis.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/MC/MCDwarf.h"
@@ -2379,6 +2381,153 @@ bool RISCVFrameLowering::canUseAsEpilogue(const MachineBasicBlock &MBB) const {
return SuccMBB->isReturnBlock() && SuccMBB->size() == 1;
}
+struct CFIBuildInfo {
+ MachineBasicBlock *MBB;
+ MachineInstr *InsertAfterMI; // nullptr means insert at MBB.begin()
+ DebugLoc DL;
+ unsigned CFIIndex;
+};
+
+class EarlyCFIEmitter {
+public:
+ EarlyCFIEmitter(MachineFunction &MF_, const ReachingDefInfo &RDI_,
+ const RISCVInstrInfo &TII_, const RISCVRegisterInfo &TRI_,
+ const RISCVFrameLowering &TFI_)
+ : MF{MF_}, RDI{RDI_}, TII{TII_}, TRI{TRI_}, TFI{TFI_} {};
+ void trackRegisterAndEmitCFIs(
+ Register Reg, int64_t DwarfEHRegNum, MachineInstr &MI,
+ SmallVectorImpl<CFIBuildInfo> &CFIBuildInfos,
+ SmallPtrSetImpl<MachineInstr *> &VisitedRestorePoints,
+ SmallPtrSetImpl<MachineInstr *> &VisitedDefs);
+
+private:
+ MachineFunction &MF;
+ const ReachingDefInfo &RDI;
+ const RISCVInstrInfo &TII;
+ const RISCVRegisterInfo &TRI;
+ const RISCVFrameLowering &TFI;
+};
+
+void EarlyCFIEmitter::trackRegisterAndEmitCFIs(
+ Register Reg, int64_t DwarfEHRegNum, MachineInstr &MI,
+ SmallVectorImpl<CFIBuildInfo> &CFIBuildInfos,
+ SmallPtrSetImpl<MachineInstr *> &VisitedRestorePoints,
+ SmallPtrSetImpl<MachineInstr *> &VisitedDefs) {
+ if (VisitedRestorePoints.find(&MI) != VisitedRestorePoints.end())
+ return;
+ VisitedRestorePoints.insert(&MI);
+
+ SmallPtrSet<MachineInstr *, 2> Defs;
+ RDI.getGlobalReachingDefs(&MI, Reg, Defs);
+ if (Defs.empty())
+ // it's a live-in register at the entry block.
+ return;
+
+ int FrameIndex = std::numeric_limits<int>::min();
+ for (MachineInstr *Def : Defs) {
+ if (VisitedDefs.find(Def) != VisitedDefs.end())
+ continue;
+ VisitedDefs.insert(Def);
+
+ MachineBasicBlock &MBB = *Def->getParent();
+ const DebugLoc &DL = Def->getDebugLoc();
+
+ if (Register StoredReg = TII.isStoreToStackSlot(*Def, FrameIndex)) {
+ assert(FrameIndex == Reg.stackSlotIndex());
+
+ Register FrameReg;
+ StackOffset Offset = TFI.getFrameIndexReference(MF, FrameIndex, FrameReg);
+ int64_t FixedOffset = Offset.getFixed();
+ int64_t ScalableOffset = Offset.getScalable();
+
+ std::string CommentBuffer;
+ llvm::raw_string_ostream Comment(CommentBuffer);
+ int DwarfEHFrameReg = TRI.getDwarfRegNum(FrameReg, true);
+ Register LLVMReg = *TRI.getLLVMRegNum(DwarfEHRegNum, true);
+ Comment << printReg(LLVMReg, &TRI) << " @";
+ Comment << printReg(FrameReg, &TRI) << " + ";
+ Comment << "vlenb * " << ScalableOffset << " + ";
+ Comment << FixedOffset;
+ unsigned CFIIndex = MF.addFrameInst(
+ MCCFIInstruction::createLLVMRegAtScalableOffsetFromReg(
+ nullptr, DwarfEHRegNum, DwarfEHFrameReg, ScalableOffset,
+ FixedOffset, SMLoc(), Comment.str()));
+
+ CFIBuildInfos.push_back({&MBB, Def, DL, CFIIndex});
+ trackRegisterAndEmitCFIs(StoredReg, DwarfEHRegNum, *Def, CFIBuildInfos,
+ VisitedRestorePoints, VisitedDefs);
+ } else if (Register LoadedReg = TII.isLoadFromStackSlot(*Def, FrameIndex)) {
+ assert(LoadedReg == Reg);
+
+ unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRegister(
+ nullptr, DwarfEHRegNum, TRI.getDwarfRegNum(LoadedReg, true)));
+ CFIBuildInfos.push_back({&MBB, Def, DL, CFIIndex});
+ trackRegisterAndEmitCFIs(Register::index2StackSlot(FrameIndex),
+ DwarfEHRegNum, *Def, CFIBuildInfos,
+ VisitedRestorePoints, VisitedDefs);
+ } else if (auto DstSrc = TII.isCopyInstr(*Def)) {
+ Register DstReg = DstSrc->Destination->getReg();
+ Register SrcReg = DstSrc->Source->getReg();
+ assert(DstReg == Reg);
+
+ unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRegister(
+ nullptr, DwarfEHRegNum, TRI.getDwarfRegNum(DstReg, true)));
+ CFIBuildInfos.push_back({&MBB, Def, DL, CFIIndex});
+ trackRegisterAndEmitCFIs(SrcReg, DwarfEHRegNum, *Def, CFIBuildInfos,
+ VisitedRestorePoints, VisitedDefs);
+ } else
+ llvm_unreachable("Unexpected instruction");
+ }
+ return;
+}
+
+void RISCVFrameLowering::emitCFIsEarly(MachineFunction &MF,
+ ReachingDefInfo &RDI) const {
+ BitVector EarlyCSRs;
+ determineEarlyCalleeSaves(MF, EarlyCSRs);
+
+ SmallVector<MachineInstr *, 4> RestorePoints;
+ for (MachineBasicBlock &MBB : MF) {
+ if (MBB.isReturnBlock())
+ RestorePoints.push_back(&MBB.back());
+ }
+ SmallVector<CFIBuildInfo, 32> CFIBuildInfos;
+ const RISCVInstrInfo &TII = *STI.getInstrInfo();
+ const RISCVRegisterInfo &TRI = *STI.getRegisterInfo();
+ EarlyCFIEmitter EarlyCFIE(MF, RDI, TII, TRI, *STI.getFrameLowering());
+ const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs();
+ for (unsigned i = 0; CSRegs[i]; ++i) {
+ unsigned Reg = CSRegs[i];
+ if (!EarlyCSRs[Reg])
+ continue;
+ SmallPtrSet<MachineInstr *, 32> VisitedDefs;
+ for (MachineInstr *RestorePoint : RestorePoints) {
+ SmallPtrSet<MachineInstr *, 32> VisitedRestorePoints;
+ EarlyCFIE.trackRegisterAndEmitCFIs(Reg, TRI.getDwarfRegNum(Reg, true),
+ *RestorePoint, CFIBuildInfos,
+ VisitedRestorePoints, VisitedDefs);
+ }
+ }
+ for (CFIBuildInfo &Info : CFIBuildInfos) {
+ MachineBasicBlock *MBB = Info.MBB;
+ if (Info.InsertAfterMI) {
+ auto Bundler =
+ MIBundleBuilder(*MBB, ++(Info.InsertAfterMI->getIterator()));
+ Bundler.append(Info.InsertAfterMI->removeFromParent());
+ Bundler.append(
+ BuildMI(MBB, Info.DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(Info.CFIIndex)
+ ->removeFromParent());
+ finalizeBundle(*MBB, Bundler.begin(), Bundler.end());
+ } else {
+ BuildMI(*MBB, MBB->begin(), Info.DL,
+ TII.get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(Info.CFIIndex);
+ }
+ }
+ return;
+}
+
bool RISCVFrameLowering::isSupportedStackID(TargetStackID::Value ID) const {
switch (ID) {
case TargetStackID::Default:
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.h b/llvm/lib/Target/RISCV/RISCVFrameLowering.h
index b1835877ecd31..0658203def349 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.h
@@ -74,6 +74,8 @@ class RISCVFrameLowering : public TargetFrameLowering {
bool enableShrinkWrapping(const MachineFunction &MF) const override;
+ void emitCFIsEarly(MachineFunction &MF, ReachingDefInfo &RDI) const override;
+
bool isSupportedStackID(TargetStackID::Value ID) const override;
TargetStackID::Value getStackIDForScalableVectors() const override;
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
index 3dcad527304a6..ef1576db80bd5 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -75,9 +75,10 @@ static cl::opt<bool> EnablePExtCodeGen(
"only partial codegen is currently supported)"),
cl::init(false), cl::Hidden);
-static cl::opt<bool> SaveCSREarly("riscv-save-csrs-early",
- cl::desc("Save CSRs early"),
- cl::init(false), cl::Hidden);
+static cl::opt<bool> RISCVSaveCSRsEarly(
+ "riscv-save-csrs-early",
+ cl::desc("Let register alloctor do csr saves/restores"), cl::init(false),
+ cl::Hidden);
void RISCVSubtarget::anchor() {}
@@ -221,8 +222,8 @@ bool RISCVSubtarget::enableMachinePipeliner() const {
return getSchedModel().hasInstrSchedModel();
}
- /// Enable use of alias analysis during code generation (during MI
- /// scheduling, DAGCombine, etc.).
+/// Enable use of alias analysis during code generation (during MI
+/// scheduling, DAGCombine, etc.).
bool RISCVSubtarget::useAA() const { return UseAA; }
unsigned RISCVSubtarget::getMinimumJumpTableEntries() const {
@@ -270,6 +271,4 @@ bool RISCVSubtarget::useMIPSCCMovInsn() const {
return UseMIPSCCMovInsn && HasVendorXMIPSCMov;
}
-bool RISCVSubtarget::savesCSRsEarly() const {
- return SaveCSREarly;
-}
+bool RISCVSubtarget::savesCSRsEarly() const { return RISCVSaveCSRsEarly; }
diff --git a/llvm/test/CodeGen/RISCV/O0-pipeline.ll b/llvm/test/CodeGen/RISCV/O0-pipeline.ll
index 8714b286374a5..b308fc82a5489 100644
--- a/llvm/test/CodeGen/RISCV/O0-pipeline.ll
+++ b/llvm/test/CodeGen/RISCV/O0-pipeline.ll
@@ -54,6 +54,7 @@
; CHECK-NEXT: Fixup Statepoint Caller Saved
; CHECK-NEXT: Lazy Machine Block Frequency Analysis
; CHECK-NEXT: Machine Optimization Remark Emitter
+; CHECK-NEXT: Reaching Definitions Analysis
; CHECK-NEXT: Prologue/Epilogue Insertion & Frame Finalization
; CHECK-NEXT: Post-RA pseudo instruction expansion pass
; CHECK-NEXT: RISC-V post-regalloc pseudo instruction expansion pass
diff --git a/llvm/test/CodeGen/RISCV/O3-pipeline.ll b/llvm/test/CodeGen/RISCV/O3-pipeline.ll
index 3e2de780524b6..5111971f18cc2 100644
--- a/llvm/test/CodeGen/RISCV/O3-pipeline.ll
+++ b/llvm/test/CodeGen/RISCV/O3-pipeline.ll
@@ -175,6 +175,7 @@
; CHECK-NEXT: Lazy Machine Block Frequency Analysis
; CHECK-NEXT: Machine Optimization Remark Emitter
; CHECK-NEXT: Shrink Wrapping analysis
+; CHECK-NEXT: Reaching Definitions Analysis
; CHECK-NEXT: Prologue/Epilogue Insertion & Frame Finalization
; CHECK-NEXT: Machine Late Instructions Cleanup Pass
; CHECK-NEXT: Control Flow Optimizer
diff --git a/llvm/test/CodeGen/RISCV/emit-early-cfis.mir b/llvm/test/CodeGen/RISCV/emit-early-cfis.mir
new file mode 100644
index 0000000000000..6788f1d6548be
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/emit-early-cfis.mir
@@ -0,0 +1,108 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc %s -mtriple=riscv64 -riscv-save-csrs-early=true \
+# RUN: -run-pass=prologepilog -o - | FileCheck %s
+---
+name: test0
+tracksRegLiveness: true
+stack:
+ - { id: 0, name: '', type: default, offset: 0, size: 4, alignment: 4,
+ stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body: |
+ bb.0.entry:
+ liveins: $x18
+ ; CHECK-LABEL: name: test0
+ ; CHECK: liveins: $x18
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x2 = frame-setup ADDI $x2, -16
+ ; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
+ ; CHECK-NEXT: BUNDLE implicit $x18 {
+ ; CHECK-NEXT: SD $x18, %stack.0, 0 :: (store (s64))
+ ; CHECK-NEXT: CFI_INSTRUCTION llvm_reg_at_scalable_offset_from_reg $x18, $x2, 0, 12
+ ; CHECK-NEXT: }
+ ; CHECK-NEXT: BUNDLE implicit-def $x18 {
+ ; CHECK-NEXT: $x18 = LD %stack.0, 0 :: (load (s64))
+ ; CHECK-NEXT: CFI_INSTRUCTION register $x18, $x18
+ ; CHECK-NEXT: }
+ ; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 16
+ ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION def_cfa_offset 0
+ ; CHECK-NEXT: PseudoRET
+ SD $x18, %stack.0, 0 :: (store (s64))
+ $x18 = LD %stack.0, 0 :: (load (s64))
+ PseudoRET
+
+...
+
+---
+name: test1
+tracksRegLiveness: true
+stack:
+ - { id: 0, name: '', type: default, offset: 0, size: 4, alignment: 4,
+ stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body: |
+ bb.0.entry:
+ liveins: $x18
+ ; CHECK-LABEL: name: test1
+ ; CHECK: liveins: $x18
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x2 = frame-setup ADDI $x2, -16
+ ; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
+ ; CHECK-NEXT: BUNDLE implicit-def $x5, implicit $x18 {
+ ; CHECK-NEXT: $x5 = COPY $x18
+ ; CHECK-NEXT: CFI_INSTRUCTION register $x18, $x5
+ ; CHECK-NEXT: }
+ ; CHECK-NEXT: BUNDLE implicit-def $x18, implicit $x5 {
+ ; CHECK-NEXT: $x18 = COPY $x5
+ ; CHECK-NEXT: CFI_INSTRUCTION register $x18, $x18
+ ; CHECK-NEXT: }
+ ; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 16
+ ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION def_cfa_offset 0
+ ; CHECK-NEXT: PseudoRET
+ $x5 = COPY $x18
+ $x18 = COPY $x5
+ PseudoRET
+
+...
+
+---
+name: test2
+tracksRegLiveness: true
+stack:
+ - { id: 0, name: '', type: default, offset: 0, size: 4, alignment: 4,
+ stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body: |
+ bb.0.entry:
+ liveins: $x18
+ ; CHECK-LABEL: name: test2
+ ; CHECK: liveins: $x18
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $x2 = frame-setup ADDI $x2, -16
+ ; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
+ ; CHECK-NEXT: BUNDLE implicit-def $x5, implicit $x18 {
+ ; CHECK-NEXT: $x5 = COPY $x18
+ ; CHECK-NEXT: CFI_INSTRUCTION register $x18, $x5
+ ; CHECK-NEXT: }
+ ; CHECK-NEXT: BUNDLE implicit $x5 {
+ ; CHECK-NEXT: SD $x5, %stack.0, 0 :: (store (s64))
+ ; CHECK-NEXT: CFI_INSTRUCTION llvm_reg_at_scalable_offset_from_reg $x18, $x2, 0, 12
+ ; CHECK-NEXT: }
+ ; CHECK-NEXT: BUNDLE implicit-def $x5 {
+ ; CHECK-NEXT: $x5 = LD %stack.0, 0 :: (load (s64))
+ ; CHECK-NEXT: CFI_INSTRUCTION register $x18, $x5
+ ; CHECK-NEXT: }
+ ; CHECK-NEXT: BUNDLE implicit-def $x18, implicit $x5 {
+ ; CHECK-NEXT: $x18 = COPY $x5
+ ; CHECK-NEXT: CFI_INSTRUCTION register $x18, $x18
+ ; CHECK-NEXT: }
+ ; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 16
+ ; CHECK-NEXT: frame-destroy CFI_INSTRUCTION def_cfa_offset 0
+ ; CHECK-NEXT: PseudoRET
+ $x5 = COPY $x18
+ SD $x5, %stack.0, 0 :: (store (s64))
+ $x5 = LD %stack.0, 0 :: (load (s64))
+ $x18 = COPY $x5
+ PseudoRET
+
+...
``````````
</details>
https://github.com/llvm/llvm-project/pull/170610
More information about the llvm-branch-commits
mailing list