Skip to content

Conversation

@ppenzin
Copy link
Contributor

@ppenzin ppenzin commented Dec 4, 2025

Mikhail Gudim added 2 commits December 3, 2025 15:56
This is needed for the cases when RDA has to run on a function that
does not have live-ins info.
In `finalizeLowering` we copy all callee-saved registers from a physical
register to a virtual one. In all return blocks we copy do the reverse.
This has two effects:
  (1) It tells the optimizer that the value of callee-saved registers
  has to be preserved
  (2) Allows the optimizer to work on CSRs. In particular, we get
  shrink-wrapping "for free" - the register allocator will spill /
  restore CSRs if needed.
@llvmbot
Copy link
Member

llvmbot commented Dec 4, 2025

@llvm/pr-subscribers-backend-risc-v

Author: Petr Penzin (ppenzin)

Changes

Use register allocator to save callee-saved registers.

This has been split out from https://github.com/mgudim/llvm-project/tree/save_csr_in_ra3, and is PR 5 out of 5.

Co-authored-by: Mikhail Gudim <mgudim@ventanamicro.com>


Full diff: https://github.com/llvm/llvm-project/pull/170611.diff

9 Files Affected:

  • (modified) llvm/lib/CodeGen/ReachingDefAnalysis.cpp (+12)
  • (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+92)
  • (modified) llvm/lib/Target/RISCV/RISCVISelLowering.h (+2)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.cpp (+8)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.h (+2)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.td (+3)
  • (modified) llvm/test/CodeGen/RISCV/pr53662.mir (+4)
  • (modified) llvm/test/CodeGen/RISCV/rvv/fixed-vectors-emergency-slot.mir (+1-1)
  • (added) llvm/test/CodeGen/RISCV/save-csr-early.ll (+113)
diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
index b12a5bc64ca0b..7014fd4bf890b 100644
--- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
+++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
@@ -9,6 +9,8 @@
 #include "llvm/CodeGen/ReachingDefAnalysis.h"
 #include "llvm/ADT/SetOperations.h"
 #include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/CodeGen/LivePhysRegs.h"
 #include "llvm/CodeGen/LiveRegUnits.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
@@ -288,6 +290,16 @@ void ReachingDefInfo::run(MachineFunction &mf) {
   TRI = STI.getRegisterInfo();
   TII = STI.getInstrInfo();
   LLVM_DEBUG(dbgs() << "********** REACHING DEFINITION ANALYSIS **********\n");
+
+  MachineFunctionProperties &Props = MF->getProperties();
+  if (!Props.hasTracksLiveness()) {
+    Props.setTracksLiveness();
+
+    SmallVector<MachineBasicBlock *> AllMBBsInPostOrder;
+    for (MachineBasicBlock *MBB : post_order(MF))
+      AllMBBsInPostOrder.push_back(MBB);
+    fullyRecomputeLiveIns(AllMBBsInPostOrder);
+  }
   init();
   traverse();
 }
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index ab2652eac3823..7e7af8d48da0b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -25827,3 +25827,95 @@ bool RISCVTargetLowering::isReassocProfitable(SelectionDAG &DAG, SDValue N0,
 
   return true;
 }
+
+static MachineInstr *findInstrWhichNeedAllCSRs(MachineBasicBlock &MBB) {
+  // Some instructions may require (implicitly) all CSRs to be saved.
+  // For example, call to __cxa_throw is noreturn, but expects that all CSRs are
+  // taken care of.
+  // TODO: try to speedup this?
+  for (MachineInstr &MI : MBB) {
+    unsigned Opc = MI.getOpcode();
+    if (Opc != RISCV::PseudoCALL && Opc != RISCV::PseudoTAIL)
+      continue;
+    MachineOperand &MO = MI.getOperand(0);
+    StringRef Name = "";
+    if (MO.isSymbol()) {
+      Name = MO.getSymbolName();
+    } else if (MO.isGlobal()) {
+      Name = MO.getGlobal()->getName();
+    } else {
+      llvm_unreachable("Unexpected operand type.");
+    }
+    if (Name == "__cxa_throw" || Name == "__cxa_rethrow" ||
+        Name == "_Unwind_Resume")
+      return &MI;
+  }
+  return nullptr;
+}
+
+void RISCVTargetLowering::finalizeLowering(MachineFunction &MF) const {
+  if (!Subtarget.savesCSRsEarly()) {
+    TargetLoweringBase::finalizeLowering(MF);
+    return;
+  }
+
+  MachineRegisterInfo &MRI = MF.getRegInfo();
+  const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
+  const RISCVRegisterInfo &TRI = *Subtarget.getRegisterInfo();
+  const RISCVFrameLowering &TFI = *Subtarget.getFrameLowering();
+
+  SmallVector<MachineInstr *, 4> RestorePoints;
+  SmallVector<MachineBasicBlock *, 4> SaveMBBs;
+  SaveMBBs.push_back(&MF.front());
+  for (MachineBasicBlock &MBB : MF) {
+    if (MBB.isReturnBlock())
+      RestorePoints.push_back(&MBB.back());
+    if (MachineInstr *CallToCxaThrow = findInstrWhichNeedAllCSRs(MBB)) {
+      MachineBasicBlock::iterator MII = MBB.getFirstTerminator();
+      MachineInstr *NewRetMI = BuildMI(MBB, MII, CallToCxaThrow->getDebugLoc(),
+                                       TII.get(RISCV::UnreachableRET));
+      RestorePoints.push_back(NewRetMI);
+      MII = ++NewRetMI->getIterator();
+      MBB.erase(MII, MBB.end());
+    }
+  }
+
+  BitVector EarlyCSRs;
+  TFI.determineEarlyCalleeSaves(MF, EarlyCSRs);
+
+  SmallVector<Register, 4> VRegs;
+  for (MachineBasicBlock *SaveMBB : SaveMBBs) {
+    for (unsigned Reg = 0; Reg < EarlyCSRs.size(); ++Reg) {
+      if (!EarlyCSRs[Reg])
+        continue;
+      SaveMBB->addLiveIn(Reg);
+      Register VReg = MRI.createVirtualRegister(
+          TRI.getLargestLegalSuperClass(TRI.getMinimalPhysRegClass(Reg), MF));
+      VRegs.push_back(VReg);
+      BuildMI(*SaveMBB, SaveMBB->begin(),
+              SaveMBB->findDebugLoc(SaveMBB->begin()),
+              TII.get(TargetOpcode::COPY), VReg)
+          .addReg(Reg);
+      MRI.setSimpleHint(VReg, Reg);
+    }
+  }
+
+  for (MachineInstr *RestorePoint : RestorePoints) {
+    auto VRegI = VRegs.begin();
+    for (unsigned Reg = 0; Reg < EarlyCSRs.size(); ++Reg) {
+      if (!EarlyCSRs[Reg])
+        continue;
+      Register VReg = *VRegI;
+      BuildMI(*RestorePoint->getParent(), RestorePoint->getIterator(),
+              RestorePoint->getDebugLoc(), TII.get(TargetOpcode::COPY), Reg)
+          .addReg(VReg);
+      RestorePoint->addOperand(MF,
+                               MachineOperand::CreateReg(Reg,
+                                                         /*isDef=*/false,
+                                                         /*isImplicit=*/true));
+      VRegI++;
+    }
+  }
+
+  TargetLoweringBase::finalizeLowering(MF);
+}
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index 8a55a5634452c..bd21bb9e8593e 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -652,6 +652,8 @@ class RISCVTargetLowering : public TargetLowering {
 
   std::pair<const TargetRegisterClass *, uint8_t>
   findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT) const override;
+
+  void finalizeLowering(MachineFunction &MF) const override;
 };
 
 namespace RISCVVIntrinsicsTable {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 89ec4a2a4a3e1..5bbf558644987 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -5127,3 +5127,11 @@ bool RISCVInstrInfo::isHighLatencyDef(int Opc) const {
     return true;
   }
 }
+
+bool RISCVInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
+  if (MI.getOpcode() == RISCV::UnreachableRET) {
+    MI.eraseFromParent();
+    return true;
+  }
+  return false;
+}
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
index 0ffe015b9fac8..e98ec29d57446 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
@@ -343,6 +343,8 @@ class RISCVInstrInfo : public RISCVGenInstrInfo {
   static bool isFromLoadImm(const MachineRegisterInfo &MRI,
                             const MachineOperand &Op, int64_t &Imm);
 
+  bool expandPostRAPseudo(MachineInstr &MI) const override;
+
 protected:
   const RISCVSubtarget &STI;
 
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 84b962b2a8607..3cc6cb6567cfe 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1836,6 +1836,9 @@ let isBarrier = 1, isReturn = 1, isTerminator = 1 in
 def PseudoRET : Pseudo<(outs), (ins), [(riscv_ret_glue)]>,
                 PseudoInstExpansion<(JALR X0, X1, 0)>;
 
+let isBarrier = 1, isReturn = 1, isTerminator = 1, isMeta = 1, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
+def UnreachableRET : Pseudo<(outs), (ins), []>;
+
 // PseudoTAIL is a pseudo instruction similar to PseudoCALL and will eventually
 // expand to auipc and jalr while encoding.
 // Define AsmString to print "tail" when compile with -S flag.
diff --git a/llvm/test/CodeGen/RISCV/pr53662.mir b/llvm/test/CodeGen/RISCV/pr53662.mir
index dccad40368111..834bcbc1cf82c 100644
--- a/llvm/test/CodeGen/RISCV/pr53662.mir
+++ b/llvm/test/CodeGen/RISCV/pr53662.mir
@@ -18,15 +18,19 @@ body:             |
   ; CHECK-LABEL: name: b
   ; CHECK: bb.0:
   ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $x10
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   PseudoBR %bb.1
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT: bb.1:
   ; CHECK-NEXT:   successors: %bb.2(0x80000000)
+  ; CHECK-NEXT:   liveins: $x10
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   DBG_VALUE $noreg
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   liveins: $x10
+  ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   PseudoRET implicit killed $x10
   bb.0 :
     PseudoBR %bb.1
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-emergency-slot.mir b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-emergency-slot.mir
index c728fcb8d8b0d..44f60a43a2790 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-emergency-slot.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-emergency-slot.mir
@@ -47,7 +47,7 @@ body:             |
 
     SD $x10, %stack.0, 0
     SD $x10, %stack.2, 0
-    dead renamable $x15 = PseudoVSETIVLI 1, 72, implicit-def $vl, implicit-def $vtype
+    renamable $x15 = PseudoVSETIVLI 1, 72, implicit-def $vl, implicit-def $vtype
     VS1R_V killed renamable $v25, %stack.1 :: (store (<vscale x 1 x s64>) into %stack.1, align 8)
     ; This is here just to make all the eligible registers live at this point.
     ; This way when we replace the frame index %stack.1 with its actual address
diff --git a/llvm/test/CodeGen/RISCV/save-csr-early.ll b/llvm/test/CodeGen/RISCV/save-csr-early.ll
new file mode 100644
index 0000000000000..65feb5d867aab
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/save-csr-early.ll
@@ -0,0 +1,113 @@
+; 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: -stop-after=finalize-isel -o - | FileCheck %s
+
+define void @test0() {
+  ; CHECK-LABEL: name: test0
+  ; CHECK: bb.0 (%ir-block.0):
+  ; CHECK-NEXT:   liveins: $x1, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gprjalrnonx7_and_gprnox31 = COPY $x27
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gprjalrnonx7_and_gprnox31 = COPY $x26
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gprjalrnonx7_and_gprnox31 = COPY $x25
+  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gprjalrnonx7_and_gprnox31 = COPY $x24
+  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:sr07 = COPY $x23
+  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:sr07 = COPY $x22
+  ; CHECK-NEXT:   [[COPY6:%[0-9]+]]:sr07 = COPY $x21
+  ; CHECK-NEXT:   [[COPY7:%[0-9]+]]:sr07 = COPY $x20
+  ; CHECK-NEXT:   [[COPY8:%[0-9]+]]:sr07 = COPY $x19
+  ; CHECK-NEXT:   [[COPY9:%[0-9]+]]:sr07 = COPY $x18
+  ; CHECK-NEXT:   [[COPY10:%[0-9]+]]:gprc_and_sr07 = COPY $x9
+  ; CHECK-NEXT:   [[COPY11:%[0-9]+]]:gprc_and_sr07 = COPY $x8
+  ; CHECK-NEXT:   [[COPY12:%[0-9]+]]:gprx1 = COPY $x1
+  ; CHECK-NEXT:   $x1 = COPY [[COPY12]]
+  ; CHECK-NEXT:   $x8 = COPY [[COPY11]]
+  ; CHECK-NEXT:   $x9 = COPY [[COPY10]]
+  ; CHECK-NEXT:   $x18 = COPY [[COPY9]]
+  ; CHECK-NEXT:   $x19 = COPY [[COPY8]]
+  ; CHECK-NEXT:   $x20 = COPY [[COPY7]]
+  ; CHECK-NEXT:   $x21 = COPY [[COPY6]]
+  ; CHECK-NEXT:   $x22 = COPY [[COPY5]]
+  ; CHECK-NEXT:   $x23 = COPY [[COPY4]]
+  ; CHECK-NEXT:   $x24 = COPY [[COPY3]]
+  ; CHECK-NEXT:   $x25 = COPY [[COPY2]]
+  ; CHECK-NEXT:   $x26 = COPY [[COPY1]]
+  ; CHECK-NEXT:   $x27 = COPY [[COPY]]
+  ; CHECK-NEXT:   PseudoRET implicit $x1, implicit $x8, implicit $x9, implicit $x18, implicit $x19, implicit $x20, implicit $x21, implicit $x22, implicit $x23, implicit $x24, implicit $x25, implicit $x26, implicit $x27
+  ret void
+}
+
+declare void @__cxa_throw(ptr, ptr, ptr)
+
+define void @test1(i1 %x, ptr %p0, ptr %p1, ptr %p2) {
+  ; CHECK-LABEL: name: test1
+  ; CHECK: bb.0.entry:
+  ; CHECK-NEXT:   successors: %bb.1(0x00000000), %bb.2(0x80000000)
+  ; CHECK-NEXT:   liveins: $x10, $x11, $x12, $x13, $x1, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gprjalrnonx7_and_gprnox31 = COPY $x27
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gprjalrnonx7_and_gprnox31 = COPY $x26
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gprjalrnonx7_and_gprnox31 = COPY $x25
+  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gprjalrnonx7_and_gprnox31 = COPY $x24
+  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:sr07 = COPY $x23
+  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:sr07 = COPY $x22
+  ; CHECK-NEXT:   [[COPY6:%[0-9]+]]:sr07 = COPY $x21
+  ; CHECK-NEXT:   [[COPY7:%[0-9]+]]:sr07 = COPY $x20
+  ; CHECK-NEXT:   [[COPY8:%[0-9]+]]:sr07 = COPY $x19
+  ; CHECK-NEXT:   [[COPY9:%[0-9]+]]:sr07 = COPY $x18
+  ; CHECK-NEXT:   [[COPY10:%[0-9]+]]:gprc_and_sr07 = COPY $x9
+  ; CHECK-NEXT:   [[COPY11:%[0-9]+]]:gprc_and_sr07 = COPY $x8
+  ; CHECK-NEXT:   [[COPY12:%[0-9]+]]:gprx1 = COPY $x1
+  ; CHECK-NEXT:   [[COPY13:%[0-9]+]]:gpr = COPY $x13
+  ; CHECK-NEXT:   [[COPY14:%[0-9]+]]:gpr = COPY $x12
+  ; CHECK-NEXT:   [[COPY15:%[0-9]+]]:gpr = COPY $x11
+  ; CHECK-NEXT:   [[COPY16:%[0-9]+]]:gpr = COPY $x10
+  ; CHECK-NEXT:   [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY16]], 1
+  ; CHECK-NEXT:   BEQ killed [[ANDI]], $x0, %bb.2
+  ; CHECK-NEXT:   PseudoBR %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1.throw:
+  ; CHECK-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def dead $x2, implicit $x2
+  ; CHECK-NEXT:   $x10 = COPY [[COPY15]]
+  ; CHECK-NEXT:   $x11 = COPY [[COPY14]]
+  ; CHECK-NEXT:   $x12 = COPY [[COPY13]]
+  ; CHECK-NEXT:   PseudoCALL target-flags(riscv-call) @__cxa_throw, csr_ilp32_lp64, implicit-def dead $x1, implicit $x10, implicit $x11, implicit $x12, implicit-def $x2
+  ; CHECK-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def dead $x2, implicit $x2
+  ; CHECK-NEXT:   $x1 = COPY [[COPY12]]
+  ; CHECK-NEXT:   $x8 = COPY [[COPY11]]
+  ; CHECK-NEXT:   $x9 = COPY [[COPY10]]
+  ; CHECK-NEXT:   $x18 = COPY [[COPY9]]
+  ; CHECK-NEXT:   $x19 = COPY [[COPY8]]
+  ; CHECK-NEXT:   $x20 = COPY [[COPY7]]
+  ; CHECK-NEXT:   $x21 = COPY [[COPY6]]
+  ; CHECK-NEXT:   $x22 = COPY [[COPY5]]
+  ; CHECK-NEXT:   $x23 = COPY [[COPY4]]
+  ; CHECK-NEXT:   $x24 = COPY [[COPY3]]
+  ; CHECK-NEXT:   $x25 = COPY [[COPY2]]
+  ; CHECK-NEXT:   $x26 = COPY [[COPY1]]
+  ; CHECK-NEXT:   $x27 = COPY [[COPY]]
+  ; CHECK-NEXT:   UnreachableRET implicit $x1, implicit $x8, implicit $x9, implicit $x18, implicit $x19, implicit $x20, implicit $x21, implicit $x22, implicit $x23, implicit $x24, implicit $x25, implicit $x26, implicit $x27
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2.return:
+  ; CHECK-NEXT:   $x1 = COPY [[COPY12]]
+  ; CHECK-NEXT:   $x8 = COPY [[COPY11]]
+  ; CHECK-NEXT:   $x9 = COPY [[COPY10]]
+  ; CHECK-NEXT:   $x18 = COPY [[COPY9]]
+  ; CHECK-NEXT:   $x19 = COPY [[COPY8]]
+  ; CHECK-NEXT:   $x20 = COPY [[COPY7]]
+  ; CHECK-NEXT:   $x21 = COPY [[COPY6]]
+  ; CHECK-NEXT:   $x22 = COPY [[COPY5]]
+  ; CHECK-NEXT:   $x23 = COPY [[COPY4]]
+  ; CHECK-NEXT:   $x24 = COPY [[COPY3]]
+  ; CHECK-NEXT:   $x25 = COPY [[COPY2]]
+  ; CHECK-NEXT:   $x26 = COPY [[COPY1]]
+  ; CHECK-NEXT:   $x27 = COPY [[COPY]]
+  ; CHECK-NEXT:   PseudoRET implicit $x1, implicit $x8, implicit $x9, implicit $x18, implicit $x19, implicit $x20, implicit $x21, implicit $x22, implicit $x23, implicit $x24, implicit $x25, implicit $x26, implicit $x27
+entry:
+  br i1 %x, label %throw, label %return
+throw:
+  call void @__cxa_throw(ptr %p0, ptr %p1, ptr %p2)
+  unreachable
+return:
+  ret void
+}

@github-actions
Copy link

github-actions bot commented Dec 4, 2025

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff origin/main HEAD --extensions cpp,h -- llvm/lib/CodeGen/ReachingDefAnalysis.cpp llvm/lib/Target/RISCV/RISCVISelLowering.cpp llvm/lib/Target/RISCV/RISCVISelLowering.h llvm/lib/Target/RISCV/RISCVInstrInfo.cpp llvm/lib/Target/RISCV/RISCVInstrInfo.h --diff_from_common_commit

⚠️
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing origin/main to the base branch/commit you want to compare against.
⚠️

View the diff from clang-format here.
diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
index 7014fd4bf..f36beabbd 100644
--- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
+++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
@@ -7,9 +7,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/ReachingDefAnalysis.h"
+#include "llvm/ADT/PostOrderIterator.h"
 #include "llvm/ADT/SetOperations.h"
 #include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/PostOrderIterator.h"
 #include "llvm/CodeGen/LivePhysRegs.h"
 #include "llvm/CodeGen/LiveRegUnits.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"

@github-actions
Copy link

github-actions bot commented Dec 4, 2025

🐧 Linux x64 Test Results

  • 3053 tests passed
  • 7 tests skipped

All tests passed but another part of the build failed. Click on a failure below to see the details.

lib/DWARFCFIChecker/CMakeFiles/LLVMDWARFCFIChecker.dir/DWARFCFIState.cpp.o
FAILED: lib/DWARFCFIChecker/CMakeFiles/LLVMDWARFCFIChecker.dir/DWARFCFIState.cpp.o
sccache /opt/llvm/bin/clang++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/DWARFCFIChecker -I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/lib/DWARFCFIChecker -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include -gmlt -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG -std=c++17  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -MD -MT lib/DWARFCFIChecker/CMakeFiles/LLVMDWARFCFIChecker.dir/DWARFCFIState.cpp.o -MF lib/DWARFCFIChecker/CMakeFiles/LLVMDWARFCFIChecker.dir/DWARFCFIState.cpp.o.d -o lib/DWARFCFIChecker/CMakeFiles/LLVMDWARFCFIChecker.dir/DWARFCFIState.cpp.o -c /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/lib/DWARFCFIChecker/DWARFCFIState.cpp
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/lib/DWARFCFIChecker/DWARFCFIState.cpp:67:11: error: enumeration values 'OpLLVMDefCfaRegScalableOffset', 'OpLLVMRegAtScalableOffsetFromCfa', and 'OpLLVMRegAtScalableOffsetFromReg' not handled in switch [-Werror,-Wswitch]
67 |   switch (Directive.getOperation()) {
|           ^~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
lib/Target/AArch64/CMakeFiles/LLVMAArch64CodeGen.dir/AArch64FrameLowering.cpp.o
FAILED: lib/Target/AArch64/CMakeFiles/LLVMAArch64CodeGen.dir/AArch64FrameLowering.cpp.o
sccache /opt/llvm/bin/clang++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/Target/AArch64 -I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/lib/Target/AArch64 -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include -gmlt -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG -std=c++17 -fvisibility=hidden  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -MD -MT lib/Target/AArch64/CMakeFiles/LLVMAArch64CodeGen.dir/AArch64FrameLowering.cpp.o -MF lib/Target/AArch64/CMakeFiles/LLVMAArch64CodeGen.dir/AArch64FrameLowering.cpp.o.d -o lib/Target/AArch64/CMakeFiles/LLVMAArch64CodeGen.dir/AArch64FrameLowering.cpp.o -c /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp:2495:24: error: 'determineCalleeSaves' is deprecated: Use determinePrologCalleeSaves instead [-Werror,-Wdeprecated-declarations]
2495 |   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
|                        ^~~~~~~~~~~~~~~~~~~~
|                        determinePrologCalleeSaves
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include/llvm/CodeGen/TargetFrameLowering.h:400:3: note: 'determineCalleeSaves' has been explicitly marked deprecated here
400 |   LLVM_DEPRECATED("Use determinePrologCalleeSaves instead",
|   ^
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include/llvm/Support/Compiler.h:250:50: note: expanded from macro 'LLVM_DEPRECATED'
250 | #define LLVM_DEPRECATED(MSG, FIX) __attribute__((deprecated(MSG, FIX)))
|                                                  ^
1 error generated.
tools/bolt/lib/Core/CMakeFiles/LLVMBOLTCore.dir/BinaryFunction.cpp.o
FAILED: tools/bolt/lib/Core/CMakeFiles/LLVMBOLTCore.dir/BinaryFunction.cpp.o
sccache /opt/llvm/bin/clang++ -DCMAKE_INSTALL_FULL_LIBDIR=\"/home/gha/actions-runner/_work/llvm-project/llvm-project/build/install/lib\" -DGTEST_HAS_RTTI=0 -DLLVM_BUILD_STATIC -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/bolt/lib/Core -I/home/gha/actions-runner/_work/llvm-project/llvm-project/bolt/lib/Core -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/bolt/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/bolt/include -gmlt -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG -std=c++17  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -MD -MT tools/bolt/lib/Core/CMakeFiles/LLVMBOLTCore.dir/BinaryFunction.cpp.o -MF tools/bolt/lib/Core/CMakeFiles/LLVMBOLTCore.dir/BinaryFunction.cpp.o.d -o tools/bolt/lib/Core/CMakeFiles/LLVMBOLTCore.dir/BinaryFunction.cpp.o -c /home/gha/actions-runner/_work/llvm-project/llvm-project/bolt/lib/Core/BinaryFunction.cpp
/home/gha/actions-runner/_work/llvm-project/llvm-project/bolt/lib/Core/BinaryFunction.cpp:2751:13: error: enumeration values 'OpLLVMDefCfaRegScalableOffset', 'OpLLVMRegAtScalableOffsetFromCfa', and 'OpLLVMRegAtScalableOffsetFromReg' not handled in switch [-Werror,-Wswitch]
2751 |     switch (Instr.getOperation()) {
|             ^~~~~~~~~~~~~~~~~~~~
/home/gha/actions-runner/_work/llvm-project/llvm-project/bolt/lib/Core/BinaryFunction.cpp:2878:13: error: enumeration values 'OpLLVMDefCfaRegScalableOffset', 'OpLLVMRegAtScalableOffsetFromCfa', and 'OpLLVMRegAtScalableOffsetFromReg' not handled in switch [-Werror,-Wswitch]
2878 |     switch (Instr.getOperation()) {
|             ^~~~~~~~~~~~~~~~~~~~
/home/gha/actions-runner/_work/llvm-project/llvm-project/bolt/lib/Core/BinaryFunction.cpp:3024:13: error: enumeration values 'OpLLVMDefCfaRegScalableOffset', 'OpLLVMRegAtScalableOffsetFromCfa', and 'OpLLVMRegAtScalableOffsetFromReg' not handled in switch [-Werror,-Wswitch]
3024 |     switch (Instr.getOperation()) {
|             ^~~~~~~~~~~~~~~~~~~~
3 errors generated.
lib/Target/RISCV/CMakeFiles/LLVMRISCVCodeGen.dir/RISCVFrameLowering.cpp.o
FAILED: lib/Target/RISCV/CMakeFiles/LLVMRISCVCodeGen.dir/RISCVFrameLowering.cpp.o
sccache /opt/llvm/bin/clang++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/Target/RISCV -I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/lib/Target/RISCV -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include -gmlt -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG -std=c++17 -fvisibility=hidden  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -MD -MT lib/Target/RISCV/CMakeFiles/LLVMRISCVCodeGen.dir/RISCVFrameLowering.cpp.o -MF lib/Target/RISCV/CMakeFiles/LLVMRISCVCodeGen.dir/RISCVFrameLowering.cpp.o.d -o lib/Target/RISCV/CMakeFiles/LLVMRISCVCodeGen.dir/RISCVFrameLowering.cpp.o -c /home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp:1541:28: error: unused variable 'TRI' [-Werror,-Wunused-variable]
1541 |   const RISCVRegisterInfo *TRI = STI.getRegisterInfo();
|                            ^~~
1 error generated.

If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the infrastructure label.

@ppenzin ppenzin changed the title [WIP] Users/ppenzin/ra saverestore codegen [WIP][CodeGen] Allow register allocator to drive save/restore Dec 4, 2025
@ppenzin ppenzin requested a review from mgudim December 4, 2025 06:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants