https://github.com/ppenzin created 
https://github.com/llvm/llvm-project/pull/170610

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 <[email protected]>

>From 48b49aa918c18afc71389bdde4ceaec8b3a775ca Mon Sep 17 00:00:00 2001
From: Mikhail Gudim <[email protected]>
Date: Fri, 19 Sep 2025 11:36:21 -0700
Subject: [PATCH] Emit early CFIs

Add ability to emit CFIs if the registers were saved / restored
before prolog / epilog insertion.
---
 .../llvm/CodeGen/TargetFrameLowering.h        |  27 ++--
 llvm/lib/CodeGen/PrologEpilogInserter.cpp     |  18 ++-
 llvm/lib/Target/RISCV/RISCVFrameLowering.cpp  | 149 ++++++++++++++++++
 llvm/lib/Target/RISCV/RISCVFrameLowering.h    |   2 +
 llvm/lib/Target/RISCV/RISCVSubtarget.cpp      |  15 +-
 llvm/test/CodeGen/RISCV/O0-pipeline.ll        |   1 +
 llvm/test/CodeGen/RISCV/O3-pipeline.ll        |   1 +
 llvm/test/CodeGen/RISCV/emit-early-cfis.mir   | 108 +++++++++++++
 8 files changed, 300 insertions(+), 21 deletions(-)
 create mode 100644 llvm/test/CodeGen/RISCV/emit-early-cfis.mir

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
+
+...

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to