[llvm] [RISCV] Mark SiFive CLIC epilogue instructions as frame-destroy (PR #218338)

via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 24 01:21:11 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

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

Author: Zeyi Xu (zeyi2)

<details>
<summary>Changes</summary>

SiFive CLIC interrupt epilogue instructions were incorrectly marked as `FrameSetup`. This commit marks the restore sequence and final stack swap as `FrameDestroy`.

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


3 Files Affected:

- (modified) llvm/docs/ReleaseNotes.md (+2) 
- (modified) llvm/lib/Target/RISCV/RISCVFrameLowering.cpp (+10-9) 
- (added) llvm/test/CodeGen/RISCV/sifive-interrupt-frame-flags.ll (+30) 


``````````diff
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 051d726b7aa8d..5549e9aa9dbcd 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -122,6 +122,8 @@ Makes programs 10x faster by doing Special New Thing.
   vectoring extensions.
 * Added experimental MC support for the `Smip` and `Ssip` interrupt handler
   push/pop extensions.
+* Fixed SiFive CLIC interrupt epilogue instructions being incorrectly marked as
+  frame setup code.
 * Bump Svukte extension to 1.0.
 * Remove experimental from Zicfiss.
 
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 35a36497d4f65..801802670dfd4 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -232,7 +232,8 @@ static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB,
 // Insert instruction to swap mscratchsw with sp
 static void emitSiFiveCLICStackSwap(MachineFunction &MF, MachineBasicBlock &MBB,
                                     MachineBasicBlock::iterator MBBI,
-                                    const DebugLoc &DL) {
+                                    const DebugLoc &DL,
+                                    MachineInstr::MIFlag FrameFlag) {
   auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
 
   if (!RVFI->isSiFiveStackSwapInterrupt(MF))
@@ -247,7 +248,7 @@ static void emitSiFiveCLICStackSwap(MachineFunction &MF, MachineBasicBlock &MBB,
       .addReg(SPReg, RegState::Define)
       .addImm(RISCVSysReg::sf_mscratchcsw)
       .addReg(SPReg, RegState::Kill)
-      .setMIFlag(MachineInstr::FrameSetup);
+      .setMIFlag(FrameFlag);
 
   // FIXME: CFI Information for this swap.
 }
@@ -344,7 +345,7 @@ static void emitSiFiveCLICPreemptibleRestores(MachineFunction &MF,
       .addReg(RISCV::X0, RegState::Define)
       .addImm(RISCVSysReg::mstatus)
       .addImm(8)
-      .setMIFlag(MachineInstr::FrameSetup);
+      .setMIFlag(MachineInstr::FrameDestroy);
 
   // Restore `mepc` from x9 (s1), and `mcause` from x8 (s0). If either were used
   // in the function, they have already been restored once, so now have the
@@ -353,23 +354,23 @@ static void emitSiFiveCLICPreemptibleRestores(MachineFunction &MF,
       .addReg(RISCV::X0, RegState::Define)
       .addImm(RISCVSysReg::mepc)
       .addReg(RISCV::X9, RegState::Kill)
-      .setMIFlag(MachineInstr::FrameSetup);
+      .setMIFlag(MachineInstr::FrameDestroy);
   BuildMI(MBB, MBBI, DL, TII->get(RISCV::CSRRW))
       .addReg(RISCV::X0, RegState::Define)
       .addImm(RISCVSysReg::mcause)
       .addReg(RISCV::X8, RegState::Kill)
-      .setMIFlag(MachineInstr::FrameSetup);
+      .setMIFlag(MachineInstr::FrameDestroy);
 
   // X8 and X9 need to be restored to their values on function entry, which we
   // saved onto the stack in `emitSiFiveCLICPreemptibleSaves`.
   TII->loadRegFromStackSlot(MBB, MBBI, RISCV::X9,
                             RVFI->getInterruptCSRFrameIndex(1),
                             &RISCV::GPRRegClass, Register(),
-                            RISCV::NoSubRegister, MachineInstr::FrameSetup);
+                            RISCV::NoSubRegister, MachineInstr::FrameDestroy);
   TII->loadRegFromStackSlot(MBB, MBBI, RISCV::X8,
                             RVFI->getInterruptCSRFrameIndex(0),
                             &RISCV::GPRRegClass, Register(),
-                            RISCV::NoSubRegister, MachineInstr::FrameSetup);
+                            RISCV::NoSubRegister, MachineInstr::FrameDestroy);
 }
 
 // Get the ID of the libcall used for spilling and restoring callee saved
@@ -1002,7 +1003,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
     return;
 
   // SiFive CLIC needs to swap `sp` into `sf.mscratchcsw`
-  emitSiFiveCLICStackSwap(MF, MBB, MBBI, DL);
+  emitSiFiveCLICStackSwap(MF, MBB, MBBI, DL, MachineInstr::FrameSetup);
 
   // Emit prologue for shadow call stack.
   emitSCSPrologue(MF, MBB, MBBI, DL);
@@ -1480,7 +1481,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
   emitSCSEpilogue(MF, MBB, MBBI, DL);
 
   // SiFive CLIC needs to swap `sf.mscratchcsw` into `sp`
-  emitSiFiveCLICStackSwap(MF, MBB, MBBI, DL);
+  emitSiFiveCLICStackSwap(MF, MBB, MBBI, DL, MachineInstr::FrameDestroy);
 }
 
 static MCRegister getPhysicalGPR(const TargetRegisterInfo &TRI,
diff --git a/llvm/test/CodeGen/RISCV/sifive-interrupt-frame-flags.ll b/llvm/test/CodeGen/RISCV/sifive-interrupt-frame-flags.ll
new file mode 100644
index 0000000000000..e014c20febfb8
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/sifive-interrupt-frame-flags.ll
@@ -0,0 +1,30 @@
+; RUN: llc < %s -mtriple=riscv32 -mattr=+experimental-xsfmclic \
+; RUN:   -verify-machineinstrs -stop-after=prolog-epilog -o - \
+; RUN:   | FileCheck %s
+; RUN: llc < %s -mtriple=riscv64 -mattr=+experimental-xsfmclic \
+; RUN:   -verify-machineinstrs -stop-after=prolog-epilog -o - \
+; RUN:   | FileCheck %s
+
+define void @preemptible_stack_swap() "interrupt"="SiFive-CLIC-preemptible-stack-swap" {
+; CHECK-LABEL: name: preemptible_stack_swap
+; CHECK: body:             |
+; CHECK-NEXT:   bb.0
+; CHECK-NEXT:     $x2 = frame-setup CSRRW 840, killed $x2
+; CHECK-NEXT:     $x2 = frame-setup ADDI $x2, -16
+; CHECK-NEXT:     frame-setup CFI_INSTRUCTION def_cfa_offset 16
+; CHECK-NEXT:     frame-setup {{SW|SD}} killed $x8
+; CHECK-NEXT:     frame-setup {{SW|SD}} killed $x9
+; CHECK-NEXT:     $x8 = frame-setup CSRRS 834, $x0
+; CHECK-NEXT:     $x9 = frame-setup CSRRS 833, $x0
+; CHECK-NEXT:     $x0 = frame-setup CSRRSI 768, 8
+; CHECK-NEXT:     $x0 = frame-destroy CSRRCI 768, 8
+; CHECK-NEXT:     $x0 = frame-destroy CSRRW 833, killed $x9
+; CHECK-NEXT:     $x0 = frame-destroy CSRRW 834, killed $x8
+; CHECK-NEXT:     $x9 = frame-destroy {{LW|LD}}
+; CHECK-NEXT:     $x8 = frame-destroy {{LW|LD}}
+; CHECK-NEXT:     $x2 = frame-destroy ADDI $x2, 16
+; CHECK-NEXT:     frame-destroy CFI_INSTRUCTION def_cfa_offset 0
+; CHECK-NEXT:     $x2 = frame-destroy CSRRW 840, killed $x2
+; CHECK-NEXT:     MRET
+  ret void
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/218338


More information about the llvm-commits mailing list