-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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 #110234
Conversation
@llvm/pr-subscribers-llvm-globalisel @llvm/pr-subscribers-debuginfo Author: None (dlav-sc) ChangesThis patch adds information about cfa value and registers' frame location
Patch is 1017.35 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/110234.diff 296 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 22824b77c37dd6..777b26f0a002f5 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -755,11 +755,32 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
}
}
+void RISCVFrameLowering::deallocateStack(MachineFunction &MF,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ 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,
MachineBasicBlock &MBB) const {
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);
@@ -786,20 +807,67 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
--MBBI;
}
- const auto &CSI = getUnmanagedCSI(MF, MFI.getCalleeSavedInfo());
+ const auto &CSI = MFI.getCalleeSavedInfo();
// Skip to before the restores of scalar callee-saved registers
// FIXME: assumes exactly one instruction is used to restore each
// callee-saved register.
- auto LastFrameDestroy = MBBI;
- if (!CSI.empty())
- LastFrameDestroy = std::prev(MBBI, CSI.size());
+ auto LastFrameDestroy = std::prev(MBBI, getUnmanagedCSI(MF, CSI).size());
- uint64_t RealStackSize = getStackSizeWithRVVPadding(MF);
- uint64_t StackSize = RealStackSize - RVFI->getReservedSpillsSize();
- uint64_t FPOffset = RealStackSize - RVFI->getVarArgsSaveSize();
+ uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
+ uint64_t RealStackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
+ : getStackSizeWithRVVPadding(MF);
+ uint64_t StackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
+ : getStackSizeWithRVVPadding(MF) -
+ RVFI->getReservedSpillsSize();
+ uint64_t FPOffset = FirstSPAdjustAmount ? FirstSPAdjustAmount
+ : getStackSizeWithRVVPadding(MF) -
+ RVFI->getVarArgsSaveSize();
uint64_t RVVStackSize = RVFI->getRVVStackSize();
+ bool restoreFP = RI->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
+ !hasReservedCallFrame(MF);
+
+ if (RVVStackSize) {
+ // If restoreFP the stack pointer will be restored using the frame pointer
+ // value.
+ 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) {
+ uint64_t SecondSPAdjustAmount =
+ getStackSizeWithRVVPadding(MF) - FirstSPAdjustAmount;
+ assert(SecondSPAdjustAmount > 0 &&
+ "SecondSPAdjustAmount should be greater than zero");
+
+ // If restoreFP the stack pointer will be restored using the frame pointer
+ // value.
+ if (!restoreFP) {
+ 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);
+ }
+ }
+
// Restore the stack pointer using the value of the frame pointer. Only
// necessary if the stack pointer was modified, meaning the stack size is
// unknown.
@@ -810,35 +878,21 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
// normally it's just checking the variable sized object is present or not
// is enough, but we also don't preserve that at prologue/epilogue when
// have vector objects in stack.
- if (RI->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
- !hasReservedCallFrame(MF)) {
- assert(hasFP(MF) && "frame pointer should not have been eliminated");
+ if (restoreFP) {
RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg,
- StackOffset::getFixed(-FPOffset),
- MachineInstr::FrameDestroy, getStackAlign());
- } else {
- if (RVVStackSize)
- adjustStackForRVV(MF, MBB, LastFrameDestroy, DL, RVVStackSize,
- MachineInstr::FrameDestroy);
- }
-
- uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
- if (FirstSPAdjustAmount) {
- uint64_t SecondSPAdjustAmount =
- getStackSizeWithRVVPadding(MF) - FirstSPAdjustAmount;
- assert(SecondSPAdjustAmount > 0 &&
- "SecondSPAdjustAmount should be greater than zero");
+ StackOffset::getFixed(-FPOffset), MachineInstr::FrameDestroy,
+ getStackAlign());
- RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg,
- StackOffset::getFixed(SecondSPAdjustAmount),
- 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);
}
- if (FirstSPAdjustAmount)
- StackSize = FirstSPAdjustAmount;
-
- if (RVFI->isPushable(MF) && MBBI != MBB.end() &&
- MBBI->getOpcode() == RISCV::CM_POP) {
+ bool ApplyPop = RVFI->isPushable(MF) && MBBI != MBB.end() &&
+ MBBI->getOpcode() == RISCV::CM_POP;
+ if (ApplyPop) {
// Use available stack adjustment in pop instruction to deallocate stack
// space. Align the stack size down to a multiple of 16. This is needed for
// RVE.
@@ -846,14 +900,36 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
uint64_t Spimm = std::min(alignDown(StackSize, 16), (uint64_t)48);
MBBI->getOperand(1).setImm(Spimm);
StackSize -= Spimm;
+
+ if (StackSize != 0)
+ 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);
}
- // Deallocate stack
- if (StackSize != 0) {
- RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(StackSize),
- MachineInstr::FrameDestroy, getStackAlign());
+ // 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
+ // during cm.pop handling.
+ if (StackSize != 0 && !ApplyPop)
+ deallocateStack(MF, MBB, MBBI, DL, StackSize, 0);
+
// Emit epilogue for shadow call stack.
emitSCSEpilogue(MF, MBB, MBBI, DL);
}
@@ -1557,6 +1633,7 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
int FI = CS.getFrameIdx();
if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector) {
MCRegister BaseReg = TRI.getSubReg(CS.getReg(), RISCV::sub_vrm1_0);
+
// If it's not a grouped vector register, it doesn't have subregister, so
// the base register is just itself.
if (BaseReg == RISCV::NoRegister)
@@ -1576,6 +1653,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 28ab4aff3b9d51..68402bf9d81478 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.h
@@ -88,9 +88,17 @@ class RISCVFrameLowering : public TargetFrameLowering {
void adjustStackForRVV(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
int64_t Amount, MachineInstr::MIFlag Flag) const;
+
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,
+ uint64_t StackSize, int64_t CFAOffset) const;
+
std::pair<int64_t, Align>
assignRVVStackObjectOffsets(MachineFunction &MF) const;
};
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 a49d4de6e9cf0d..b9a17eac802072 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 pt...
[truncated]
|
@llvm/pr-subscribers-backend-risc-v Author: None (dlav-sc) ChangesThis patch adds information about cfa value and registers' frame location
Patch is 1017.35 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/110234.diff 296 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 22824b77c37dd6..777b26f0a002f5 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -755,11 +755,32 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
}
}
+void RISCVFrameLowering::deallocateStack(MachineFunction &MF,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ 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,
MachineBasicBlock &MBB) const {
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);
@@ -786,20 +807,67 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
--MBBI;
}
- const auto &CSI = getUnmanagedCSI(MF, MFI.getCalleeSavedInfo());
+ const auto &CSI = MFI.getCalleeSavedInfo();
// Skip to before the restores of scalar callee-saved registers
// FIXME: assumes exactly one instruction is used to restore each
// callee-saved register.
- auto LastFrameDestroy = MBBI;
- if (!CSI.empty())
- LastFrameDestroy = std::prev(MBBI, CSI.size());
+ auto LastFrameDestroy = std::prev(MBBI, getUnmanagedCSI(MF, CSI).size());
- uint64_t RealStackSize = getStackSizeWithRVVPadding(MF);
- uint64_t StackSize = RealStackSize - RVFI->getReservedSpillsSize();
- uint64_t FPOffset = RealStackSize - RVFI->getVarArgsSaveSize();
+ uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
+ uint64_t RealStackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
+ : getStackSizeWithRVVPadding(MF);
+ uint64_t StackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
+ : getStackSizeWithRVVPadding(MF) -
+ RVFI->getReservedSpillsSize();
+ uint64_t FPOffset = FirstSPAdjustAmount ? FirstSPAdjustAmount
+ : getStackSizeWithRVVPadding(MF) -
+ RVFI->getVarArgsSaveSize();
uint64_t RVVStackSize = RVFI->getRVVStackSize();
+ bool restoreFP = RI->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
+ !hasReservedCallFrame(MF);
+
+ if (RVVStackSize) {
+ // If restoreFP the stack pointer will be restored using the frame pointer
+ // value.
+ 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) {
+ uint64_t SecondSPAdjustAmount =
+ getStackSizeWithRVVPadding(MF) - FirstSPAdjustAmount;
+ assert(SecondSPAdjustAmount > 0 &&
+ "SecondSPAdjustAmount should be greater than zero");
+
+ // If restoreFP the stack pointer will be restored using the frame pointer
+ // value.
+ if (!restoreFP) {
+ 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);
+ }
+ }
+
// Restore the stack pointer using the value of the frame pointer. Only
// necessary if the stack pointer was modified, meaning the stack size is
// unknown.
@@ -810,35 +878,21 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
// normally it's just checking the variable sized object is present or not
// is enough, but we also don't preserve that at prologue/epilogue when
// have vector objects in stack.
- if (RI->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
- !hasReservedCallFrame(MF)) {
- assert(hasFP(MF) && "frame pointer should not have been eliminated");
+ if (restoreFP) {
RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg,
- StackOffset::getFixed(-FPOffset),
- MachineInstr::FrameDestroy, getStackAlign());
- } else {
- if (RVVStackSize)
- adjustStackForRVV(MF, MBB, LastFrameDestroy, DL, RVVStackSize,
- MachineInstr::FrameDestroy);
- }
-
- uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
- if (FirstSPAdjustAmount) {
- uint64_t SecondSPAdjustAmount =
- getStackSizeWithRVVPadding(MF) - FirstSPAdjustAmount;
- assert(SecondSPAdjustAmount > 0 &&
- "SecondSPAdjustAmount should be greater than zero");
+ StackOffset::getFixed(-FPOffset), MachineInstr::FrameDestroy,
+ getStackAlign());
- RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg,
- StackOffset::getFixed(SecondSPAdjustAmount),
- 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);
}
- if (FirstSPAdjustAmount)
- StackSize = FirstSPAdjustAmount;
-
- if (RVFI->isPushable(MF) && MBBI != MBB.end() &&
- MBBI->getOpcode() == RISCV::CM_POP) {
+ bool ApplyPop = RVFI->isPushable(MF) && MBBI != MBB.end() &&
+ MBBI->getOpcode() == RISCV::CM_POP;
+ if (ApplyPop) {
// Use available stack adjustment in pop instruction to deallocate stack
// space. Align the stack size down to a multiple of 16. This is needed for
// RVE.
@@ -846,14 +900,36 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
uint64_t Spimm = std::min(alignDown(StackSize, 16), (uint64_t)48);
MBBI->getOperand(1).setImm(Spimm);
StackSize -= Spimm;
+
+ if (StackSize != 0)
+ 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);
}
- // Deallocate stack
- if (StackSize != 0) {
- RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(StackSize),
- MachineInstr::FrameDestroy, getStackAlign());
+ // 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
+ // during cm.pop handling.
+ if (StackSize != 0 && !ApplyPop)
+ deallocateStack(MF, MBB, MBBI, DL, StackSize, 0);
+
// Emit epilogue for shadow call stack.
emitSCSEpilogue(MF, MBB, MBBI, DL);
}
@@ -1557,6 +1633,7 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
int FI = CS.getFrameIdx();
if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector) {
MCRegister BaseReg = TRI.getSubReg(CS.getReg(), RISCV::sub_vrm1_0);
+
// If it's not a grouped vector register, it doesn't have subregister, so
// the base register is just itself.
if (BaseReg == RISCV::NoRegister)
@@ -1576,6 +1653,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 28ab4aff3b9d51..68402bf9d81478 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.h
@@ -88,9 +88,17 @@ class RISCVFrameLowering : public TargetFrameLowering {
void adjustStackForRVV(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
int64_t Amount, MachineInstr::MIFlag Flag) const;
+
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,
+ uint64_t StackSize, int64_t CFAOffset) const;
+
std::pair<int64_t, Align>
assignRVVStackObjectOffsets(MachineFunction &MF) const;
};
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 a49d4de6e9cf0d..b9a17eac802072 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 pt...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
7794518
to
9fc61a1
Compare
612e6af
to
f342944
Compare
Does this resolve the issues that caused this to get removed originally https://reviews.llvm.org/D69723 Here's another attempt at this https://reviews.llvm.org/D111519 |
e726995
to
b6a7d6b
Compare
This patch adds information about cfa value and registers frame location in function's epilogue, that allows to obtain a valid backtrace at the end of functions. Also it fixes the stack pointer recovery from the frame pointer if the frame pointer is used. Before patch: %bb.0: addi sp, sp, -16 .cfi_def_cfa_offset 16 sw ra, 12(sp) # 4-byte Folded Spill sw s0, 8(sp) # 4-byte Folded Spill .cfi_offset ra, -4 .cfi_offset s0, -8 addi s0, sp, 16 .cfi_def_cfa s0, 0 lw ra, 12(sp) # 4-byte Folded Reload lw s0, 8(sp) # 4-byte Folded Reload addi sp, sp, 16 ret After patch: %bb.0: addi sp, sp, -16 .cfi_def_cfa_offset 16 sw ra, 12(sp) # 4-byte Folded Spill sw s0, 8(sp) # 4-byte Folded Spill .cfi_offset ra, -4 .cfi_offset s0, -8 addi s0, sp, 16 .cfi_def_cfa s0, 0 addi sp, s0, -16 .cfi_def_cfa sp, 16 lw ra, 12(sp) # 4-byte Folded Reload lw s0, 8(sp) # 4-byte Folded Reload .cfi_restore ra .cfi_restore s0 addi sp, sp, 16 .cfi_def_cfa_offset 0 ret
Could you take a look this https://reviews.llvm.org/D114545? and try to enable that for RISC-V to address the issue that Craig mention. |
I didn't know about these attempts,
Thanks, I'll try |
I added @topperc @kito-cheng could you take a look, please? |
@@ -432,7 +432,8 @@ define void @callee() nounwind { | |||
; RV32IZCMP-NEXT: sw a0, %lo(var+4)(a6) | |||
; RV32IZCMP-NEXT: lw a0, 28(sp) # 4-byte Folded Reload | |||
; RV32IZCMP-NEXT: sw a0, %lo(var)(a6) | |||
; RV32IZCMP-NEXT: cm.popret {ra, s0-s11}, 96 | |||
; RV32IZCMP-NEXT: cm.pop {ra, s0-s11}, 96 |
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.
What happened here?
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.
Nevermind. I see this is fixed by #110236
DebugLoc DL = MBB.findDebugLoc(MI); | ||
|
||
const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, MFI.getCalleeSavedInfo()); | ||
if (RVVCSI.empty()) |
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.
Is this if
necessary. The loop should see the vector is empty and do nothing.
@@ -1557,6 +1633,7 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI( | |||
int FI = CS.getFrameIdx(); | |||
if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector) { | |||
MCRegister BaseReg = TRI.getSubReg(CS.getReg(), RISCV::sub_vrm1_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.
Unrelated formatting change?
uint64_t RVVStackSize = RVFI->getRVVStackSize(); | ||
|
||
bool restoreFP = RI->hasStackRealignment(MF) || MFI.hasVarSizedObjects() || |
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.
Variable names should be capitalized
|
||
// Update CFA offset. After CM_POP SP should be equal to CFA, so CFA offset | ||
// is zero. | ||
MBBI = std::next(MBBI); |
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.
++MBBI?
; CHECK-NEXT: $x2 = frame-destroy ADDI $x8, -2048 | ||
; CHECK-NEXT: $x2 = frame-destroy ADDI killed $x2, -224 | ||
; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 240 | ||
; CHECK-NEXT: $x2 = frame-destroy ADDI $x8, -2032 |
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.
Is it possible to split the patch so that we get the changes to ADDIs here without the new CFI instructions? It's really hard to review all of the tests to see if anything changes other than CFI directives.
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
63ddb10
to
bf67b57
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.
Debug info gen is fine, just found one issue around the save-restore routine :)
; 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.
The CFI directive should emit after the tail call, otherwise debugger will confused when stop at add a0, s0, a0
; 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 | |
; ILP32E-FPELIM-SAVE-RESTORE-NEXT: tail __riscv_restore_1 | |
; ILP32E-FPELIM-SAVE-RESTORE-NEXT: .cfi_restore ra | |
; ILP32E-FPELIM-SAVE-RESTORE-NEXT: .cfi_restore s0 |
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_restore ra | ||
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_restore s0 | ||
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_restore s1 | ||
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: tail __riscv_restore_2 |
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.
Same issue here
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_restore ra | ||
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_restore s0 | ||
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: addi sp, sp, 12 | ||
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_def_cfa_offset 0 | ||
; ILP32E-WITHFP-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.
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_restore ra | |
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_restore s0 | |
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: addi sp, sp, 12 | |
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_def_cfa_offset 0 | |
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: tail __riscv_restore_1 | |
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: addi sp, sp, 12 | |
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_def_cfa_offset 8 | |
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: tail __riscv_restore_1 | |
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_restore ra | |
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_restore s0 | |
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_def_cfa_offset 0 |
Or something like below is fine, (this is not precise enough but it's separate issue which is not introduced by your fix)
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: addi sp, sp, 12
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: tail __riscv_restore_1
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_restore ra
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_restore s0
; ILP32E-WITHFP-SAVE-RESTORE-NEXT: .cfi_def_cfa_offset 0
This patch adds information about cfa value and registers' frame location
in function's epilogue, which allows to obtain a valid backtrace at the
end of functions.
riscv-gcc
can generate such information already, so I think it would be useful if clang will be able to generate it too.