-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RISCV][CFI] add function epilogue cfi information #110810
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-llvm-globalisel @llvm/pr-subscribers-debuginfo Author: None (dlav-sc) ChangesThis patch adds CFI instructions in a function epilogue, that allows lldb to obtain a valid backtrace at the end of functions. Patch is 1004.05 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/110810.diff 296 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 7cbd1a35b25839..78d3dafaf9c8e2 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -761,11 +761,18 @@ void RISCVFrameLowering::deallocateStack(MachineFunction &MF,
const DebugLoc &DL, uint64_t StackSize,
int64_t CFAOffset) const {
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
+ const RISCVInstrInfo *TII = STI.getInstrInfo();
Register SPReg = getSPReg(STI);
RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(StackSize),
MachineInstr::FrameDestroy, getStackAlign());
+
+ unsigned CFIIndex =
+ MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, CFAOffset));
+ BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameDestroy);
}
void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
@@ -773,6 +780,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
MachineFrameInfo &MFI = MF.getFrameInfo();
auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
+ const RISCVInstrInfo *TII = STI.getInstrInfo();
Register FPReg = getFPReg(STI);
Register SPReg = getSPReg(STI);
@@ -826,7 +834,16 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
if (!RestoreFP) {
adjustStackForRVV(MF, MBB, LastFrameDestroy, DL, RVVStackSize,
MachineInstr::FrameDestroy);
+
+ unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
+ nullptr, RI->getDwarfRegNum(SPReg, true), RealStackSize));
+ BuildMI(MBB, LastFrameDestroy, DL,
+ TII->get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameDestroy);
}
+
+ emitCalleeSavedRVVEpilogCFI(MBB, LastFrameDestroy);
}
if (FirstSPAdjustAmount) {
@@ -841,6 +858,13 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg,
StackOffset::getFixed(SecondSPAdjustAmount),
MachineInstr::FrameDestroy, getStackAlign());
+
+ unsigned CFIIndex = MF.addFrameInst(
+ MCCFIInstruction::cfiDefCfaOffset(nullptr, FirstSPAdjustAmount));
+ BuildMI(MBB, LastFrameDestroy, DL,
+ TII->get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameDestroy);
}
}
@@ -858,6 +882,12 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg,
StackOffset::getFixed(-FPOffset), MachineInstr::FrameDestroy,
getStackAlign());
+
+ unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
+ nullptr, RI->getDwarfRegNum(SPReg, true), RealStackSize));
+ BuildMI(MBB, LastFrameDestroy, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameDestroy);
}
bool ApplyPop = RVFI->isPushable(MF) && MBBI != MBB.end() &&
@@ -875,7 +905,24 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
deallocateStack(MF, MBB, MBBI, DL, StackSize,
/*stack_adj of cm.pop instr*/ RealStackSize - StackSize);
+ // Update CFA offset. After CM_POP SP should be equal to CFA, so CFA offset
+ // is zero.
MBBI = std::next(MBBI);
+ unsigned CFIIndex =
+ MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, 0));
+ BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameDestroy);
+ }
+
+ // Recover callee-saved registers.
+ for (const auto &Entry : CSI) {
+ Register Reg = Entry.getReg();
+ unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
+ nullptr, RI->getDwarfRegNum(Reg, true)));
+ BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameDestroy);
}
// Deallocate stack if StackSize isn't a zero and if we didn't already do it
@@ -1615,6 +1662,31 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
}
}
+void RISCVFrameLowering::emitCalleeSavedRVVEpilogCFI(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const {
+ MachineFunction *MF = MBB.getParent();
+ const MachineFrameInfo &MFI = MF->getFrameInfo();
+ const RISCVRegisterInfo *RI = STI.getRegisterInfo();
+ const TargetInstrInfo &TII = *STI.getInstrInfo();
+ DebugLoc DL = MBB.findDebugLoc(MI);
+
+ const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, MFI.getCalleeSavedInfo());
+ if (RVVCSI.empty())
+ return;
+
+ for (auto &CS : RVVCSI) {
+ int FI = CS.getFrameIdx();
+ if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector) {
+ Register Reg = CS.getReg();
+ unsigned CFIIndex = MF->addFrameInst(MCCFIInstruction::createRestore(
+ nullptr, RI->getDwarfRegNum(Reg, true)));
+ BuildMI(MBB, MI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameDestroy);
+ }
+ }
+}
+
bool RISCVFrameLowering::restoreCalleeSavedRegisters(
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.h b/llvm/lib/Target/RISCV/RISCVFrameLowering.h
index 89f95f2aa04aa6..68402bf9d81478 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.h
@@ -92,6 +92,8 @@ class RISCVFrameLowering : public TargetFrameLowering {
void emitCalleeSavedRVVPrologCFI(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
bool HasFP) const;
+ void emitCalleeSavedRVVEpilogCFI(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI) const;
void deallocateStack(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/stacksave-stackrestore.ll b/llvm/test/CodeGen/RISCV/GlobalISel/stacksave-stackrestore.ll
index 014283cf38b26b..caa749729ce198 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/stacksave-stackrestore.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/stacksave-stackrestore.ll
@@ -25,10 +25,15 @@ define void @test_scoped_alloca(i64 %n) {
; RV32-NEXT: call use_addr
; RV32-NEXT: mv sp, s1
; RV32-NEXT: addi sp, s0, -16
+; RV32-NEXT: .cfi_def_cfa sp, 16
; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
+; RV32-NEXT: .cfi_restore ra
+; RV32-NEXT: .cfi_restore s0
+; RV32-NEXT: .cfi_restore s1
; RV32-NEXT: addi sp, sp, 16
+; RV32-NEXT: .cfi_def_cfa_offset 0
; RV32-NEXT: ret
;
; RV64-LABEL: test_scoped_alloca:
@@ -51,10 +56,15 @@ define void @test_scoped_alloca(i64 %n) {
; RV64-NEXT: call use_addr
; RV64-NEXT: mv sp, s1
; RV64-NEXT: addi sp, s0, -32
+; RV64-NEXT: .cfi_def_cfa sp, 32
; RV64-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
+; RV64-NEXT: .cfi_restore ra
+; RV64-NEXT: .cfi_restore s0
+; RV64-NEXT: .cfi_restore s1
; RV64-NEXT: addi sp, sp, 32
+; RV64-NEXT: .cfi_def_cfa_offset 0
; RV64-NEXT: ret
%sp = call ptr @llvm.stacksave.p0()
%addr = alloca i8, i64 %n
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll b/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll
index 01cab0d0e157bd..5ea87499d2c855 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll
@@ -59,6 +59,7 @@ define i32 @va1(ptr %fmt, ...) {
; RV32-NEXT: sw a1, 12(sp)
; RV32-NEXT: lw a0, 0(a0)
; RV32-NEXT: addi sp, sp, 48
+; RV32-NEXT: .cfi_def_cfa_offset 0
; RV32-NEXT: ret
;
; RV64-LABEL: va1:
@@ -84,6 +85,7 @@ define i32 @va1(ptr %fmt, ...) {
; RV64-NEXT: sw a2, 12(sp)
; RV64-NEXT: lw a0, 0(a0)
; RV64-NEXT: addi sp, sp, 80
+; RV64-NEXT: .cfi_def_cfa_offset 0
; RV64-NEXT: ret
;
; RV32-WITHFP-LABEL: va1:
@@ -111,7 +113,10 @@ define i32 @va1(ptr %fmt, ...) {
; RV32-WITHFP-NEXT: lw a0, 0(a0)
; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: .cfi_restore ra
+; RV32-WITHFP-NEXT: .cfi_restore s0
; RV32-WITHFP-NEXT: addi sp, sp, 48
+; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV32-WITHFP-NEXT: ret
;
; RV64-WITHFP-LABEL: va1:
@@ -144,7 +149,10 @@ define i32 @va1(ptr %fmt, ...) {
; RV64-WITHFP-NEXT: lw a0, 0(a0)
; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: .cfi_restore ra
+; RV64-WITHFP-NEXT: .cfi_restore s0
; RV64-WITHFP-NEXT: addi sp, sp, 96
+; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV64-WITHFP-NEXT: ret
%va = alloca ptr
call void @llvm.va_start(ptr %va)
@@ -1588,6 +1596,7 @@ define i32 @va_large_stack(ptr %fmt, ...) {
; RV32-NEXT: lui a1, 24414
; RV32-NEXT: addi a1, a1, 304
; RV32-NEXT: add sp, sp, a1
+; RV32-NEXT: .cfi_def_cfa_offset 0
; RV32-NEXT: ret
;
; RV64-LABEL: va_large_stack:
@@ -1633,6 +1642,7 @@ define i32 @va_large_stack(ptr %fmt, ...) {
; RV64-NEXT: lui a1, 24414
; RV64-NEXT: addiw a1, a1, 336
; RV64-NEXT: add sp, sp, a1
+; RV64-NEXT: .cfi_def_cfa_offset 0
; RV64-NEXT: ret
;
; RV32-WITHFP-LABEL: va_large_stack:
@@ -1667,9 +1677,13 @@ define i32 @va_large_stack(ptr %fmt, ...) {
; RV32-WITHFP-NEXT: lui a1, 24414
; RV32-WITHFP-NEXT: addi a1, a1, -1728
; RV32-WITHFP-NEXT: add sp, sp, a1
+; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 2032
; RV32-WITHFP-NEXT: lw ra, 1996(sp) # 4-byte Folded Reload
; RV32-WITHFP-NEXT: lw s0, 1992(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: .cfi_restore ra
+; RV32-WITHFP-NEXT: .cfi_restore s0
; RV32-WITHFP-NEXT: addi sp, sp, 2032
+; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV32-WITHFP-NEXT: ret
;
; RV64-WITHFP-LABEL: va_large_stack:
@@ -1709,9 +1723,13 @@ define i32 @va_large_stack(ptr %fmt, ...) {
; RV64-WITHFP-NEXT: lui a1, 24414
; RV64-WITHFP-NEXT: addiw a1, a1, -1680
; RV64-WITHFP-NEXT: add sp, sp, a1
+; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 2032
; RV64-WITHFP-NEXT: ld ra, 1960(sp) # 8-byte Folded Reload
; RV64-WITHFP-NEXT: ld s0, 1952(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: .cfi_restore ra
+; RV64-WITHFP-NEXT: .cfi_restore s0
; RV64-WITHFP-NEXT: addi sp, sp, 2032
+; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV64-WITHFP-NEXT: ret
%large = alloca [ 100000000 x i8 ]
%va = alloca ptr
@@ -1739,6 +1757,7 @@ define iXLen @va_vprintf(ptr %fmt, ptr %arg_start) {
; RV32-NEXT: sw a1, 8(sp)
; RV32-NEXT: lw a0, 0(a0)
; RV32-NEXT: addi sp, sp, 16
+; RV32-NEXT: .cfi_def_cfa_offset 0
; RV32-NEXT: ret
;
; RV64-LABEL: va_vprintf:
@@ -1755,6 +1774,7 @@ define iXLen @va_vprintf(ptr %fmt, ptr %arg_start) {
; RV64-NEXT: sd a1, 0(sp)
; RV64-NEXT: ld a0, 0(a0)
; RV64-NEXT: addi sp, sp, 16
+; RV64-NEXT: .cfi_def_cfa_offset 0
; RV64-NEXT: ret
;
; RV32-WITHFP-LABEL: va_vprintf:
@@ -1778,7 +1798,10 @@ define iXLen @va_vprintf(ptr %fmt, ptr %arg_start) {
; RV32-WITHFP-NEXT: lw a0, 0(a0)
; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: .cfi_restore ra
+; RV32-WITHFP-NEXT: .cfi_restore s0
; RV32-WITHFP-NEXT: addi sp, sp, 16
+; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV32-WITHFP-NEXT: ret
;
; RV64-WITHFP-LABEL: va_vprintf:
@@ -1802,7 +1825,10 @@ define iXLen @va_vprintf(ptr %fmt, ptr %arg_start) {
; RV64-WITHFP-NEXT: ld a0, 0(a0)
; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: .cfi_restore ra
+; RV64-WITHFP-NEXT: .cfi_restore s0
; RV64-WITHFP-NEXT: addi sp, sp, 32
+; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV64-WITHFP-NEXT: ret
%args = alloca ptr
%args_cp = alloca ptr
@@ -1832,7 +1858,9 @@ define i32 @va_printf(ptr %fmt, ...) {
; RV32-NEXT: sw a7, 44(sp)
; RV32-NEXT: call va_vprintf
; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32-NEXT: .cfi_restore ra
; RV32-NEXT: addi sp, sp, 48
+; RV32-NEXT: .cfi_def_cfa_offset 0
; RV32-NEXT: ret
;
; RV64-LABEL: va_printf:
@@ -1853,7 +1881,9 @@ define i32 @va_printf(ptr %fmt, ...) {
; RV64-NEXT: sd a7, 72(sp)
; RV64-NEXT: call va_vprintf
; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64-NEXT: .cfi_restore ra
; RV64-NEXT: addi sp, sp, 80
+; RV64-NEXT: .cfi_def_cfa_offset 0
; RV64-NEXT: ret
;
; RV32-WITHFP-LABEL: va_printf:
@@ -1879,7 +1909,10 @@ define i32 @va_printf(ptr %fmt, ...) {
; RV32-WITHFP-NEXT: call va_vprintf
; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: .cfi_restore ra
+; RV32-WITHFP-NEXT: .cfi_restore s0
; RV32-WITHFP-NEXT: addi sp, sp, 48
+; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV32-WITHFP-NEXT: ret
;
; RV64-WITHFP-LABEL: va_printf:
@@ -1905,7 +1938,10 @@ define i32 @va_printf(ptr %fmt, ...) {
; RV64-WITHFP-NEXT: call va_vprintf
; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: .cfi_restore ra
+; RV64-WITHFP-NEXT: .cfi_restore s0
; RV64-WITHFP-NEXT: addi sp, sp, 96
+; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV64-WITHFP-NEXT: ret
%args = alloca ptr
call void @llvm.va_start(ptr %args)
diff --git a/llvm/test/CodeGen/RISCV/addrspacecast.ll b/llvm/test/CodeGen/RISCV/addrspacecast.ll
index e55a57a5167822..80a0efb043ebdf 100644
--- a/llvm/test/CodeGen/RISCV/addrspacecast.ll
+++ b/llvm/test/CodeGen/RISCV/addrspacecast.ll
@@ -28,7 +28,9 @@ define void @cast1(ptr %ptr) {
; RV32I-NEXT: .cfi_offset ra, -4
; RV32I-NEXT: call foo
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: .cfi_restore ra
; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: .cfi_def_cfa_offset 0
; RV32I-NEXT: ret
;
; RV64I-LABEL: cast1:
@@ -39,7 +41,9 @@ define void @cast1(ptr %ptr) {
; RV64I-NEXT: .cfi_offset ra, -8
; RV64I-NEXT: call foo
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: .cfi_restore ra
; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: .cfi_def_cfa_offset 0
; RV64I-NEXT: ret
%castptr = addrspacecast ptr %ptr to ptr addrspace(10)
call void @foo(ptr addrspace(10) %castptr)
diff --git a/llvm/test/CodeGen/RISCV/atomicrmw-cond-sub-clamp.ll b/llvm/test/CodeGen/RISCV/atomicrmw-cond-sub-clamp.ll
index 0d6ae3a51e2469..f22115130117a8 100644
--- a/llvm/test/CodeGen/RISCV/atomicrmw-cond-sub-clamp.ll
+++ b/llvm/test/CodeGen/RISCV/atomicrmw-cond-sub-clamp.ll
@@ -51,7 +51,12 @@ define i8 @atomicrmw_usub_cond_i8(ptr %ptr, i8 %val) {
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
+; RV32I-NEXT: .cfi_restore ra
+; RV32I-NEXT: .cfi_restore s0
+; RV32I-NEXT: .cfi_restore s1
+; RV32I-NEXT: .cfi_restore s2
; RV32I-NEXT: addi sp, sp, 32
+; RV32I-NEXT: .cfi_def_cfa_offset 0
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_usub_cond_i8:
@@ -129,7 +134,12 @@ define i8 @atomicrmw_usub_cond_i8(ptr %ptr, i8 %val) {
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
+; RV64I-NEXT: .cfi_restore ra
+; RV64I-NEXT: .cfi_restore s0
+; RV64I-NEXT: .cfi_restore s1
+; RV64I-NEXT: .cfi_restore s2
; RV64I-NEXT: addi sp, sp, 48
+; RV64I-NEXT: .cfi_def_cfa_offset 0
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_usub_cond_i8:
@@ -216,7 +226,13 @@ define i16 @atomicrmw_usub_cond_i16(ptr %ptr, i16 %val) {
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: .cfi_restore ra
+; RV32I-NEXT: .cfi_restore s0
+; RV32I-NEXT: .cfi_restore s1
+; RV32I-NEXT: .cfi_restore s2
+; RV32I-NEXT: .cfi_restore s3
; RV32I-NEXT: addi sp, sp, 32
+; RV32I-NEXT: .cfi_def_cfa_offset 0
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_usub_cond_i16:
@@ -300,7 +316,13 @@ define i16 @atomicrmw_usub_cond_i16(ptr %ptr, i16 %val) {
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: .cfi_restore ra
+; RV64I-NEXT: .cfi_restore s0
+; RV64I-NEXT: .cfi_restore s1
+; RV64I-NEXT: .cfi_restore s2
+; RV64I-NEXT: .cfi_restore s3
; RV64I-NEXT: addi sp, sp, 48
+; RV64I-NEXT: .cfi_def_cfa_offset 0
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_usub_cond_i16:
@@ -378,7 +400,11 @@ define i32 @atomicrmw_usub_cond_i32(ptr %ptr, i32 %val) {
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
+; RV32I-NEXT: .cfi_restore ra
+; RV32I-NEXT: .cfi_restore s0
+; RV32I-NEXT: .cfi_restore s1
; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: .cfi_def_cfa_offset 0
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_usub_cond_i32:
@@ -442,7 +468,12 @@ define i32 @atomicrmw_usub_cond_i32(ptr %ptr, i32 %val) {
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
+; RV64I-NEXT: .cfi_restore ra
+; RV64I-NEXT: .cfi_restore s0
+; RV64I-NEXT: .cfi_restore s1
+; RV64I-NEXT: .cfi_restore s2
; RV64I-NEXT: addi sp, sp, 48
+; RV64I-NEXT: .cfi_def_cfa_offset 0
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_usub_cond_i32:
@@ -529,7 +560,12 @@ define i64 @atomicrmw_usub_cond_i64(ptr %ptr, i64 %val) {
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
+; RV32I-NEXT: .cfi_restore ra
+; RV32I-NEXT: .cfi_restore s0
+; RV32I-NEXT: .cfi_restore s1
+; RV32I-NEXT: .cfi_restore s2
; RV32I-NEXT: addi sp, sp, 32
+; RV32I-NEXT: .cfi_def_cfa_offset 0
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_usub_cond_i64:
@@ -586,7 +622,12 @@ define i64 @atomicrmw_usub_cond_i64(ptr %ptr, i64 %val) {
; RV32IA-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
+; RV32IA-NEXT: .cfi_restore ra
+; RV32IA-NEXT: .cfi_restore s0
+; RV32IA-NEXT: .cfi_restore s1
+; RV32IA-NEXT: .cfi_restore s2
; RV32IA-NEXT: addi sp, sp, 32
+; RV32IA-NEXT: .cfi_def_cfa_offset 0
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_usub_cond_i64:
@@ -621,7 +662,11 @@ define i64 @atomicrmw_usub_cond_i64(ptr %ptr, i64 %val) {
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: .cfi_restore ra
+; RV64I-NEXT: .cfi_restore s0
+; RV64I-NEXT: .cfi_restore s1
; RV64I-NEXT: addi sp, sp, 32
+; RV64I-NEXT: .cfi_def_cfa_offset 0
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_usub_cond_i64:
@@ -686,7 +731,11 @@ define i8 @atomicrmw_usub_sat_i8(ptr %ptr, i8 %val) {
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32I-NEXT: ...
[truncated]
|
@llvm/pr-subscribers-backend-risc-v Author: None (dlav-sc) ChangesThis patch adds CFI instructions in a function epilogue, that allows lldb to obtain a valid backtrace at the end of functions. Patch is 1004.05 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/110810.diff 296 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 7cbd1a35b25839..78d3dafaf9c8e2 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -761,11 +761,18 @@ void RISCVFrameLowering::deallocateStack(MachineFunction &MF,
const DebugLoc &DL, uint64_t StackSize,
int64_t CFAOffset) const {
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
+ const RISCVInstrInfo *TII = STI.getInstrInfo();
Register SPReg = getSPReg(STI);
RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(StackSize),
MachineInstr::FrameDestroy, getStackAlign());
+
+ unsigned CFIIndex =
+ MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, CFAOffset));
+ BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameDestroy);
}
void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
@@ -773,6 +780,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
MachineFrameInfo &MFI = MF.getFrameInfo();
auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
+ const RISCVInstrInfo *TII = STI.getInstrInfo();
Register FPReg = getFPReg(STI);
Register SPReg = getSPReg(STI);
@@ -826,7 +834,16 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
if (!RestoreFP) {
adjustStackForRVV(MF, MBB, LastFrameDestroy, DL, RVVStackSize,
MachineInstr::FrameDestroy);
+
+ unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
+ nullptr, RI->getDwarfRegNum(SPReg, true), RealStackSize));
+ BuildMI(MBB, LastFrameDestroy, DL,
+ TII->get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameDestroy);
}
+
+ emitCalleeSavedRVVEpilogCFI(MBB, LastFrameDestroy);
}
if (FirstSPAdjustAmount) {
@@ -841,6 +858,13 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg,
StackOffset::getFixed(SecondSPAdjustAmount),
MachineInstr::FrameDestroy, getStackAlign());
+
+ unsigned CFIIndex = MF.addFrameInst(
+ MCCFIInstruction::cfiDefCfaOffset(nullptr, FirstSPAdjustAmount));
+ BuildMI(MBB, LastFrameDestroy, DL,
+ TII->get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameDestroy);
}
}
@@ -858,6 +882,12 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg,
StackOffset::getFixed(-FPOffset), MachineInstr::FrameDestroy,
getStackAlign());
+
+ unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
+ nullptr, RI->getDwarfRegNum(SPReg, true), RealStackSize));
+ BuildMI(MBB, LastFrameDestroy, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameDestroy);
}
bool ApplyPop = RVFI->isPushable(MF) && MBBI != MBB.end() &&
@@ -875,7 +905,24 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
deallocateStack(MF, MBB, MBBI, DL, StackSize,
/*stack_adj of cm.pop instr*/ RealStackSize - StackSize);
+ // Update CFA offset. After CM_POP SP should be equal to CFA, so CFA offset
+ // is zero.
MBBI = std::next(MBBI);
+ unsigned CFIIndex =
+ MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, 0));
+ BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameDestroy);
+ }
+
+ // Recover callee-saved registers.
+ for (const auto &Entry : CSI) {
+ Register Reg = Entry.getReg();
+ unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
+ nullptr, RI->getDwarfRegNum(Reg, true)));
+ BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameDestroy);
}
// Deallocate stack if StackSize isn't a zero and if we didn't already do it
@@ -1615,6 +1662,31 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
}
}
+void RISCVFrameLowering::emitCalleeSavedRVVEpilogCFI(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const {
+ MachineFunction *MF = MBB.getParent();
+ const MachineFrameInfo &MFI = MF->getFrameInfo();
+ const RISCVRegisterInfo *RI = STI.getRegisterInfo();
+ const TargetInstrInfo &TII = *STI.getInstrInfo();
+ DebugLoc DL = MBB.findDebugLoc(MI);
+
+ const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, MFI.getCalleeSavedInfo());
+ if (RVVCSI.empty())
+ return;
+
+ for (auto &CS : RVVCSI) {
+ int FI = CS.getFrameIdx();
+ if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector) {
+ Register Reg = CS.getReg();
+ unsigned CFIIndex = MF->addFrameInst(MCCFIInstruction::createRestore(
+ nullptr, RI->getDwarfRegNum(Reg, true)));
+ BuildMI(MBB, MI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameDestroy);
+ }
+ }
+}
+
bool RISCVFrameLowering::restoreCalleeSavedRegisters(
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.h b/llvm/lib/Target/RISCV/RISCVFrameLowering.h
index 89f95f2aa04aa6..68402bf9d81478 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.h
@@ -92,6 +92,8 @@ class RISCVFrameLowering : public TargetFrameLowering {
void emitCalleeSavedRVVPrologCFI(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
bool HasFP) const;
+ void emitCalleeSavedRVVEpilogCFI(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI) const;
void deallocateStack(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/stacksave-stackrestore.ll b/llvm/test/CodeGen/RISCV/GlobalISel/stacksave-stackrestore.ll
index 014283cf38b26b..caa749729ce198 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/stacksave-stackrestore.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/stacksave-stackrestore.ll
@@ -25,10 +25,15 @@ define void @test_scoped_alloca(i64 %n) {
; RV32-NEXT: call use_addr
; RV32-NEXT: mv sp, s1
; RV32-NEXT: addi sp, s0, -16
+; RV32-NEXT: .cfi_def_cfa sp, 16
; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
+; RV32-NEXT: .cfi_restore ra
+; RV32-NEXT: .cfi_restore s0
+; RV32-NEXT: .cfi_restore s1
; RV32-NEXT: addi sp, sp, 16
+; RV32-NEXT: .cfi_def_cfa_offset 0
; RV32-NEXT: ret
;
; RV64-LABEL: test_scoped_alloca:
@@ -51,10 +56,15 @@ define void @test_scoped_alloca(i64 %n) {
; RV64-NEXT: call use_addr
; RV64-NEXT: mv sp, s1
; RV64-NEXT: addi sp, s0, -32
+; RV64-NEXT: .cfi_def_cfa sp, 32
; RV64-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
+; RV64-NEXT: .cfi_restore ra
+; RV64-NEXT: .cfi_restore s0
+; RV64-NEXT: .cfi_restore s1
; RV64-NEXT: addi sp, sp, 32
+; RV64-NEXT: .cfi_def_cfa_offset 0
; RV64-NEXT: ret
%sp = call ptr @llvm.stacksave.p0()
%addr = alloca i8, i64 %n
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll b/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll
index 01cab0d0e157bd..5ea87499d2c855 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/vararg.ll
@@ -59,6 +59,7 @@ define i32 @va1(ptr %fmt, ...) {
; RV32-NEXT: sw a1, 12(sp)
; RV32-NEXT: lw a0, 0(a0)
; RV32-NEXT: addi sp, sp, 48
+; RV32-NEXT: .cfi_def_cfa_offset 0
; RV32-NEXT: ret
;
; RV64-LABEL: va1:
@@ -84,6 +85,7 @@ define i32 @va1(ptr %fmt, ...) {
; RV64-NEXT: sw a2, 12(sp)
; RV64-NEXT: lw a0, 0(a0)
; RV64-NEXT: addi sp, sp, 80
+; RV64-NEXT: .cfi_def_cfa_offset 0
; RV64-NEXT: ret
;
; RV32-WITHFP-LABEL: va1:
@@ -111,7 +113,10 @@ define i32 @va1(ptr %fmt, ...) {
; RV32-WITHFP-NEXT: lw a0, 0(a0)
; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: .cfi_restore ra
+; RV32-WITHFP-NEXT: .cfi_restore s0
; RV32-WITHFP-NEXT: addi sp, sp, 48
+; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV32-WITHFP-NEXT: ret
;
; RV64-WITHFP-LABEL: va1:
@@ -144,7 +149,10 @@ define i32 @va1(ptr %fmt, ...) {
; RV64-WITHFP-NEXT: lw a0, 0(a0)
; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: .cfi_restore ra
+; RV64-WITHFP-NEXT: .cfi_restore s0
; RV64-WITHFP-NEXT: addi sp, sp, 96
+; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV64-WITHFP-NEXT: ret
%va = alloca ptr
call void @llvm.va_start(ptr %va)
@@ -1588,6 +1596,7 @@ define i32 @va_large_stack(ptr %fmt, ...) {
; RV32-NEXT: lui a1, 24414
; RV32-NEXT: addi a1, a1, 304
; RV32-NEXT: add sp, sp, a1
+; RV32-NEXT: .cfi_def_cfa_offset 0
; RV32-NEXT: ret
;
; RV64-LABEL: va_large_stack:
@@ -1633,6 +1642,7 @@ define i32 @va_large_stack(ptr %fmt, ...) {
; RV64-NEXT: lui a1, 24414
; RV64-NEXT: addiw a1, a1, 336
; RV64-NEXT: add sp, sp, a1
+; RV64-NEXT: .cfi_def_cfa_offset 0
; RV64-NEXT: ret
;
; RV32-WITHFP-LABEL: va_large_stack:
@@ -1667,9 +1677,13 @@ define i32 @va_large_stack(ptr %fmt, ...) {
; RV32-WITHFP-NEXT: lui a1, 24414
; RV32-WITHFP-NEXT: addi a1, a1, -1728
; RV32-WITHFP-NEXT: add sp, sp, a1
+; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 2032
; RV32-WITHFP-NEXT: lw ra, 1996(sp) # 4-byte Folded Reload
; RV32-WITHFP-NEXT: lw s0, 1992(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: .cfi_restore ra
+; RV32-WITHFP-NEXT: .cfi_restore s0
; RV32-WITHFP-NEXT: addi sp, sp, 2032
+; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV32-WITHFP-NEXT: ret
;
; RV64-WITHFP-LABEL: va_large_stack:
@@ -1709,9 +1723,13 @@ define i32 @va_large_stack(ptr %fmt, ...) {
; RV64-WITHFP-NEXT: lui a1, 24414
; RV64-WITHFP-NEXT: addiw a1, a1, -1680
; RV64-WITHFP-NEXT: add sp, sp, a1
+; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 2032
; RV64-WITHFP-NEXT: ld ra, 1960(sp) # 8-byte Folded Reload
; RV64-WITHFP-NEXT: ld s0, 1952(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: .cfi_restore ra
+; RV64-WITHFP-NEXT: .cfi_restore s0
; RV64-WITHFP-NEXT: addi sp, sp, 2032
+; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV64-WITHFP-NEXT: ret
%large = alloca [ 100000000 x i8 ]
%va = alloca ptr
@@ -1739,6 +1757,7 @@ define iXLen @va_vprintf(ptr %fmt, ptr %arg_start) {
; RV32-NEXT: sw a1, 8(sp)
; RV32-NEXT: lw a0, 0(a0)
; RV32-NEXT: addi sp, sp, 16
+; RV32-NEXT: .cfi_def_cfa_offset 0
; RV32-NEXT: ret
;
; RV64-LABEL: va_vprintf:
@@ -1755,6 +1774,7 @@ define iXLen @va_vprintf(ptr %fmt, ptr %arg_start) {
; RV64-NEXT: sd a1, 0(sp)
; RV64-NEXT: ld a0, 0(a0)
; RV64-NEXT: addi sp, sp, 16
+; RV64-NEXT: .cfi_def_cfa_offset 0
; RV64-NEXT: ret
;
; RV32-WITHFP-LABEL: va_vprintf:
@@ -1778,7 +1798,10 @@ define iXLen @va_vprintf(ptr %fmt, ptr %arg_start) {
; RV32-WITHFP-NEXT: lw a0, 0(a0)
; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: .cfi_restore ra
+; RV32-WITHFP-NEXT: .cfi_restore s0
; RV32-WITHFP-NEXT: addi sp, sp, 16
+; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV32-WITHFP-NEXT: ret
;
; RV64-WITHFP-LABEL: va_vprintf:
@@ -1802,7 +1825,10 @@ define iXLen @va_vprintf(ptr %fmt, ptr %arg_start) {
; RV64-WITHFP-NEXT: ld a0, 0(a0)
; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: .cfi_restore ra
+; RV64-WITHFP-NEXT: .cfi_restore s0
; RV64-WITHFP-NEXT: addi sp, sp, 32
+; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV64-WITHFP-NEXT: ret
%args = alloca ptr
%args_cp = alloca ptr
@@ -1832,7 +1858,9 @@ define i32 @va_printf(ptr %fmt, ...) {
; RV32-NEXT: sw a7, 44(sp)
; RV32-NEXT: call va_vprintf
; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32-NEXT: .cfi_restore ra
; RV32-NEXT: addi sp, sp, 48
+; RV32-NEXT: .cfi_def_cfa_offset 0
; RV32-NEXT: ret
;
; RV64-LABEL: va_printf:
@@ -1853,7 +1881,9 @@ define i32 @va_printf(ptr %fmt, ...) {
; RV64-NEXT: sd a7, 72(sp)
; RV64-NEXT: call va_vprintf
; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64-NEXT: .cfi_restore ra
; RV64-NEXT: addi sp, sp, 80
+; RV64-NEXT: .cfi_def_cfa_offset 0
; RV64-NEXT: ret
;
; RV32-WITHFP-LABEL: va_printf:
@@ -1879,7 +1909,10 @@ define i32 @va_printf(ptr %fmt, ...) {
; RV32-WITHFP-NEXT: call va_vprintf
; RV32-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
+; RV32-WITHFP-NEXT: .cfi_restore ra
+; RV32-WITHFP-NEXT: .cfi_restore s0
; RV32-WITHFP-NEXT: addi sp, sp, 48
+; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV32-WITHFP-NEXT: ret
;
; RV64-WITHFP-LABEL: va_printf:
@@ -1905,7 +1938,10 @@ define i32 @va_printf(ptr %fmt, ...) {
; RV64-WITHFP-NEXT: call va_vprintf
; RV64-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; RV64-WITHFP-NEXT: .cfi_restore ra
+; RV64-WITHFP-NEXT: .cfi_restore s0
; RV64-WITHFP-NEXT: addi sp, sp, 96
+; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 0
; RV64-WITHFP-NEXT: ret
%args = alloca ptr
call void @llvm.va_start(ptr %args)
diff --git a/llvm/test/CodeGen/RISCV/addrspacecast.ll b/llvm/test/CodeGen/RISCV/addrspacecast.ll
index e55a57a5167822..80a0efb043ebdf 100644
--- a/llvm/test/CodeGen/RISCV/addrspacecast.ll
+++ b/llvm/test/CodeGen/RISCV/addrspacecast.ll
@@ -28,7 +28,9 @@ define void @cast1(ptr %ptr) {
; RV32I-NEXT: .cfi_offset ra, -4
; RV32I-NEXT: call foo
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: .cfi_restore ra
; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: .cfi_def_cfa_offset 0
; RV32I-NEXT: ret
;
; RV64I-LABEL: cast1:
@@ -39,7 +41,9 @@ define void @cast1(ptr %ptr) {
; RV64I-NEXT: .cfi_offset ra, -8
; RV64I-NEXT: call foo
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: .cfi_restore ra
; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: .cfi_def_cfa_offset 0
; RV64I-NEXT: ret
%castptr = addrspacecast ptr %ptr to ptr addrspace(10)
call void @foo(ptr addrspace(10) %castptr)
diff --git a/llvm/test/CodeGen/RISCV/atomicrmw-cond-sub-clamp.ll b/llvm/test/CodeGen/RISCV/atomicrmw-cond-sub-clamp.ll
index 0d6ae3a51e2469..f22115130117a8 100644
--- a/llvm/test/CodeGen/RISCV/atomicrmw-cond-sub-clamp.ll
+++ b/llvm/test/CodeGen/RISCV/atomicrmw-cond-sub-clamp.ll
@@ -51,7 +51,12 @@ define i8 @atomicrmw_usub_cond_i8(ptr %ptr, i8 %val) {
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
+; RV32I-NEXT: .cfi_restore ra
+; RV32I-NEXT: .cfi_restore s0
+; RV32I-NEXT: .cfi_restore s1
+; RV32I-NEXT: .cfi_restore s2
; RV32I-NEXT: addi sp, sp, 32
+; RV32I-NEXT: .cfi_def_cfa_offset 0
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_usub_cond_i8:
@@ -129,7 +134,12 @@ define i8 @atomicrmw_usub_cond_i8(ptr %ptr, i8 %val) {
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
+; RV64I-NEXT: .cfi_restore ra
+; RV64I-NEXT: .cfi_restore s0
+; RV64I-NEXT: .cfi_restore s1
+; RV64I-NEXT: .cfi_restore s2
; RV64I-NEXT: addi sp, sp, 48
+; RV64I-NEXT: .cfi_def_cfa_offset 0
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_usub_cond_i8:
@@ -216,7 +226,13 @@ define i16 @atomicrmw_usub_cond_i16(ptr %ptr, i16 %val) {
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT: .cfi_restore ra
+; RV32I-NEXT: .cfi_restore s0
+; RV32I-NEXT: .cfi_restore s1
+; RV32I-NEXT: .cfi_restore s2
+; RV32I-NEXT: .cfi_restore s3
; RV32I-NEXT: addi sp, sp, 32
+; RV32I-NEXT: .cfi_def_cfa_offset 0
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_usub_cond_i16:
@@ -300,7 +316,13 @@ define i16 @atomicrmw_usub_cond_i16(ptr %ptr, i16 %val) {
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: .cfi_restore ra
+; RV64I-NEXT: .cfi_restore s0
+; RV64I-NEXT: .cfi_restore s1
+; RV64I-NEXT: .cfi_restore s2
+; RV64I-NEXT: .cfi_restore s3
; RV64I-NEXT: addi sp, sp, 48
+; RV64I-NEXT: .cfi_def_cfa_offset 0
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_usub_cond_i16:
@@ -378,7 +400,11 @@ define i32 @atomicrmw_usub_cond_i32(ptr %ptr, i32 %val) {
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
+; RV32I-NEXT: .cfi_restore ra
+; RV32I-NEXT: .cfi_restore s0
+; RV32I-NEXT: .cfi_restore s1
; RV32I-NEXT: addi sp, sp, 16
+; RV32I-NEXT: .cfi_def_cfa_offset 0
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_usub_cond_i32:
@@ -442,7 +468,12 @@ define i32 @atomicrmw_usub_cond_i32(ptr %ptr, i32 %val) {
; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
+; RV64I-NEXT: .cfi_restore ra
+; RV64I-NEXT: .cfi_restore s0
+; RV64I-NEXT: .cfi_restore s1
+; RV64I-NEXT: .cfi_restore s2
; RV64I-NEXT: addi sp, sp, 48
+; RV64I-NEXT: .cfi_def_cfa_offset 0
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_usub_cond_i32:
@@ -529,7 +560,12 @@ define i64 @atomicrmw_usub_cond_i64(ptr %ptr, i64 %val) {
; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
+; RV32I-NEXT: .cfi_restore ra
+; RV32I-NEXT: .cfi_restore s0
+; RV32I-NEXT: .cfi_restore s1
+; RV32I-NEXT: .cfi_restore s2
; RV32I-NEXT: addi sp, sp, 32
+; RV32I-NEXT: .cfi_def_cfa_offset 0
; RV32I-NEXT: ret
;
; RV32IA-LABEL: atomicrmw_usub_cond_i64:
@@ -586,7 +622,12 @@ define i64 @atomicrmw_usub_cond_i64(ptr %ptr, i64 %val) {
; RV32IA-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
; RV32IA-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
+; RV32IA-NEXT: .cfi_restore ra
+; RV32IA-NEXT: .cfi_restore s0
+; RV32IA-NEXT: .cfi_restore s1
+; RV32IA-NEXT: .cfi_restore s2
; RV32IA-NEXT: addi sp, sp, 32
+; RV32IA-NEXT: .cfi_def_cfa_offset 0
; RV32IA-NEXT: ret
;
; RV64I-LABEL: atomicrmw_usub_cond_i64:
@@ -621,7 +662,11 @@ define i64 @atomicrmw_usub_cond_i64(ptr %ptr, i64 %val) {
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: .cfi_restore ra
+; RV64I-NEXT: .cfi_restore s0
+; RV64I-NEXT: .cfi_restore s1
; RV64I-NEXT: addi sp, sp, 32
+; RV64I-NEXT: .cfi_def_cfa_offset 0
; RV64I-NEXT: ret
;
; RV64IA-LABEL: atomicrmw_usub_cond_i64:
@@ -686,7 +731,11 @@ define i8 @atomicrmw_usub_sat_i8(ptr %ptr, i8 %val) {
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; RV32I-NEXT: ...
[truncated]
|
@topperc @kito-cheng FYI |
0573a78
to
46e215f
Compare
a58cf3f
to
ac123f9
Compare
e7e68ef
to
19d29c9
Compare
; ILP32E-FPELIM-SAVE-RESTORE-NEXT: .cfi_restore ra | ||
; ILP32E-FPELIM-SAVE-RESTORE-NEXT: .cfi_restore s0 | ||
; ILP32E-FPELIM-SAVE-RESTORE-NEXT: tail __riscv_restore_1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just put a link for the comment I leave in your prev PR to prevent I forgot this
#110234 (review)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addressed.
Yeah, I've forgotten about libcalls at all :) Anyway, I made a fix (5cf8f31) and updated tests (e6f1c94). Could you take a look, please?
However, tests don't look like you've expected, because in fact it is unnecessary to emit CFI instructions after tail __riscv_restore_1
, which is considered as a terminator. Therefor, I just removed .cfi_restore
and placed .cfi_def_cfa_offset
instructions where they should be.
✅ With the latest revision this PR passed the C/C++ code formatter. |
db0616b
to
0c83e7d
Compare
ac123f9
to
536cbea
Compare
0c83e7d
to
8c86fc2
Compare
8c86fc2
to
2d7be29
Compare
@kito-cheng @topperc, could you take another look, please? |
Sorry, those three comments were supposed to come together, like a review. Hopefully they are helpful though. Please test looking at the |
362a051
to
652e513
Compare
Thanks for your comments, they were quite useful for me
Sometimes, in order to optimize the resulting assembly, compiler can omit |
652e513
to
8e92906
Compare
Gentle ping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice update, I see the improvements!
I'm slightly confused as to why there sometimes is and sometimes is not any CFI information between a cm.pop
and a tail
/ret
. I commented on one place where I saw this.
; RV64-NEXT: .cfi_restore fs0 | ||
; RV64-NEXT: cm.pop {ra, s0}, 32 | ||
; RV64-NEXT: .cfi_def_cfa_offset 0 | ||
; RV64-NEXT: .cfi_restore ra | ||
; RV64-NEXT: .cfi_restore s0 | ||
; RV64-NEXT: .cfi_restore fs0 | ||
; RV64-NEXT: .cfi_def_cfa_offset 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks better too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I had to change CFI instructions in the prologue, otherwise, I couldn't insert .cfi_restore
after cm.pop
.
2c44cf1
to
107a646
Compare
Thanks for taking a look at the tests! I've changed the logic a bit and tried to make
Another solution always emits CFI instructions after However, if there is a guarantee that the epilogue isn't going to change after the CFI instructions emission, I expect that my current solution will stay correct. Please let me know what you think of this matter. |
I've also made a little refactoring of this patch to get rid of code dublication (#114227) |
107a646
to
5126965
Compare
This patch adds CFI instructions in a function epilogue, that allows lldb to obtain a valid backtrace at the end of functions.
5126965
to
255db2d
Compare
255db2d
to
f49dafe
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a pretty good go through the tests, and I'm pretty confident in the test output now.
I decided not to have views on the code quality of the implementation itself, partly because I note you have a refactoring follow-up PR (thanks!) and partly because FrameLowering/PEI is already a nightmare at the best of times, and this doesn't seem to make it worse.
Please wait a day or so before landing this PR, in case anyone else wants to comment.
This patch adds CFI instructions in a function epilogue, that allows lldb to obtain a valid backtrace at the end of functions.