[llvm] c81e5fa - [RISCV] Add CFI information for vector callee-saved registers (#86811)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 16 19:42:44 PDT 2024
Author: Brandon Wu
Date: 2024-04-17T10:42:40+08:00
New Revision: c81e5faa6f55d3e390b5e550f78ab08fc6a65ee9
URL: https://github.com/llvm/llvm-project/commit/c81e5faa6f55d3e390b5e550f78ab08fc6a65ee9
DIFF: https://github.com/llvm/llvm-project/commit/c81e5faa6f55d3e390b5e550f78ab08fc6a65ee9.diff
LOG: [RISCV] Add CFI information for vector callee-saved registers (#86811)
Currently the CFI offset for RVV registers are not handled entirely,
this patch add those information for either stack unwinding or
debugger to work correctly on RVV callee-saved stack object.
Depends On D154576
Differential Revision: https://reviews.llvm.org/D156846
Added:
llvm/test/CodeGen/RISCV/rvv-cfi-info.ll
Modified:
llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
llvm/lib/Target/RISCV/RISCVFrameLowering.h
llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 71672ed7b4ae7f..cb41577c5d9435 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -435,6 +435,33 @@ void RISCVFrameLowering::adjustStackForRVV(MachineFunction &MF,
Flag, getStackAlign());
}
+static void appendScalableVectorExpression(const TargetRegisterInfo &TRI,
+ SmallVectorImpl<char> &Expr,
+ int FixedOffset, int ScalableOffset,
+ llvm::raw_string_ostream &Comment) {
+ unsigned DwarfVLenB = TRI.getDwarfRegNum(RISCV::VLENB, true);
+ uint8_t Buffer[16];
+ if (FixedOffset) {
+ Expr.push_back(dwarf::DW_OP_consts);
+ Expr.append(Buffer, Buffer + encodeSLEB128(FixedOffset, Buffer));
+ Expr.push_back((uint8_t)dwarf::DW_OP_plus);
+ Comment << (FixedOffset < 0 ? " - " : " + ") << std::abs(FixedOffset);
+ }
+
+ Expr.push_back((uint8_t)dwarf::DW_OP_consts);
+ Expr.append(Buffer, Buffer + encodeSLEB128(ScalableOffset, Buffer));
+
+ Expr.push_back((uint8_t)dwarf::DW_OP_bregx);
+ Expr.append(Buffer, Buffer + encodeULEB128(DwarfVLenB, Buffer));
+ Expr.push_back(0);
+
+ Expr.push_back((uint8_t)dwarf::DW_OP_mul);
+ Expr.push_back((uint8_t)dwarf::DW_OP_plus);
+
+ Comment << (ScalableOffset < 0 ? " - " : " + ") << std::abs(ScalableOffset)
+ << " * vlenb";
+}
+
static MCCFIInstruction createDefCFAExpression(const TargetRegisterInfo &TRI,
Register Reg,
uint64_t FixedOffset,
@@ -452,30 +479,38 @@ static MCCFIInstruction createDefCFAExpression(const TargetRegisterInfo &TRI,
else
Comment << printReg(Reg, &TRI);
- uint8_t buffer[16];
- if (FixedOffset) {
- Expr.push_back(dwarf::DW_OP_consts);
- Expr.append(buffer, buffer + encodeSLEB128(FixedOffset, buffer));
- Expr.push_back((uint8_t)dwarf::DW_OP_plus);
- Comment << " + " << FixedOffset;
- }
+ appendScalableVectorExpression(TRI, Expr, FixedOffset, ScalableOffset,
+ Comment);
- Expr.push_back((uint8_t)dwarf::DW_OP_consts);
- Expr.append(buffer, buffer + encodeSLEB128(ScalableOffset, buffer));
+ SmallString<64> DefCfaExpr;
+ uint8_t Buffer[16];
+ DefCfaExpr.push_back(dwarf::DW_CFA_def_cfa_expression);
+ DefCfaExpr.append(Buffer, Buffer + encodeULEB128(Expr.size(), Buffer));
+ DefCfaExpr.append(Expr.str());
- unsigned DwarfVlenb = TRI.getDwarfRegNum(RISCV::VLENB, true);
- Expr.push_back((uint8_t)dwarf::DW_OP_bregx);
- Expr.append(buffer, buffer + encodeULEB128(DwarfVlenb, buffer));
- Expr.push_back(0);
+ return MCCFIInstruction::createEscape(nullptr, DefCfaExpr.str(), SMLoc(),
+ Comment.str());
+}
- Expr.push_back((uint8_t)dwarf::DW_OP_mul);
- Expr.push_back((uint8_t)dwarf::DW_OP_plus);
+static MCCFIInstruction createDefCFAOffset(const TargetRegisterInfo &TRI,
+ Register Reg, uint64_t FixedOffset,
+ uint64_t ScalableOffset) {
+ assert(ScalableOffset != 0 && "Did not need to adjust CFA for RVV");
+ SmallString<64> Expr;
+ std::string CommentBuffer;
+ llvm::raw_string_ostream Comment(CommentBuffer);
+ Comment << printReg(Reg, &TRI) << " @ cfa";
- Comment << " + " << ScalableOffset << " * vlenb";
+ // Build up the expression (FixedOffset + ScalableOffset * VLENB).
+ appendScalableVectorExpression(TRI, Expr, FixedOffset, ScalableOffset,
+ Comment);
SmallString<64> DefCfaExpr;
- DefCfaExpr.push_back(dwarf::DW_CFA_def_cfa_expression);
- DefCfaExpr.append(buffer, buffer + encodeULEB128(Expr.size(), buffer));
+ uint8_t Buffer[16];
+ unsigned DwarfReg = TRI.getDwarfRegNum(Reg, true);
+ DefCfaExpr.push_back(dwarf::DW_CFA_expression);
+ DefCfaExpr.append(Buffer, Buffer + encodeULEB128(DwarfReg, Buffer));
+ DefCfaExpr.append(Buffer, Buffer + encodeULEB128(Expr.size(), Buffer));
DefCfaExpr.append(Expr.str());
return MCCFIInstruction::createEscape(nullptr, DefCfaExpr.str(), SMLoc(),
@@ -671,6 +706,9 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
.addCFIIndex(CFIIndex)
.setMIFlag(MachineInstr::FrameSetup);
}
+
+ std::advance(MBBI, getRVVCalleeSavedInfo(MF, CSI).size());
+ emitCalleeSavedRVVPrologCFI(MBB, MBBI, hasFP(MF));
}
if (hasFP(MF)) {
@@ -1492,6 +1530,41 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
return true;
}
+void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, bool HasFP) const {
+ MachineFunction *MF = MBB.getParent();
+ const MachineFrameInfo &MFI = MF->getFrameInfo();
+ RISCVMachineFunctionInfo *RVFI = MF->getInfo<RISCVMachineFunctionInfo>();
+ const TargetInstrInfo &TII = *STI.getInstrInfo();
+ DebugLoc DL = MBB.findDebugLoc(MI);
+
+ const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, MFI.getCalleeSavedInfo());
+ if (RVVCSI.empty())
+ return;
+
+ uint64_t FixedSize = getStackSizeWithRVVPadding(*MF);
+ if (!HasFP) {
+ uint64_t ScalarLocalVarSize =
+ MFI.getStackSize() - RVFI->getCalleeSavedStackSize() -
+ RVFI->getRVPushStackSize() - RVFI->getVarArgsSaveSize() +
+ RVFI->getRVVPadding();
+ FixedSize -= ScalarLocalVarSize;
+ }
+
+ for (auto &CS : RVVCSI) {
+ // Insert the spill to the stack frame.
+ int FI = CS.getFrameIdx();
+ if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector) {
+ unsigned CFIIndex = MF->addFrameInst(
+ createDefCFAOffset(*STI.getRegisterInfo(), CS.getReg(), -FixedSize,
+ MFI.getObjectOffset(FI) / 8));
+ BuildMI(MBB, MI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameSetup);
+ }
+ }
+}
+
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 210f8c1064724a..28ab4aff3b9d51 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.h
@@ -88,6 +88,9 @@ 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;
std::pair<int64_t, Align>
assignRVVStackObjectOffsets(MachineFunction &MF) const;
};
diff --git a/llvm/test/CodeGen/RISCV/rvv-cfi-info.ll b/llvm/test/CodeGen/RISCV/rvv-cfi-info.ll
new file mode 100644
index 00000000000000..c99388cbdaf441
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv-cfi-info.ll
@@ -0,0 +1,111 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv64 -mattr=+v,+m -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=OMIT-FP %s
+; RUN: llc -mtriple=riscv64 -mattr=+v,+m -verify-machineinstrs -frame-pointer=all < %s \
+; RUN: | FileCheck -check-prefix=NO-OMIT-FP %s
+
+define riscv_vector_cc <vscale x 1 x i32> @test_vector_callee_cfi(<vscale x 1 x i32> %va) {
+; OMIT-FP-LABEL: test_vector_callee_cfi:
+; OMIT-FP: # %bb.0: # %entry
+; OMIT-FP-NEXT: addi sp, sp, -16
+; OMIT-FP-NEXT: .cfi_def_cfa_offset 16
+; OMIT-FP-NEXT: csrr a0, vlenb
+; OMIT-FP-NEXT: slli a0, a0, 3
+; OMIT-FP-NEXT: sub sp, sp, a0
+; OMIT-FP-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x08, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 8 * vlenb
+; OMIT-FP-NEXT: csrr a0, vlenb
+; OMIT-FP-NEXT: li a1, 6
+; OMIT-FP-NEXT: mul a0, a0, a1
+; OMIT-FP-NEXT: add a0, sp, a0
+; OMIT-FP-NEXT: addi a0, a0, 16
+; OMIT-FP-NEXT: vs1r.v v1, (a0) # Unknown-size Folded Spill
+; OMIT-FP-NEXT: csrr a0, vlenb
+; OMIT-FP-NEXT: slli a0, a0, 2
+; OMIT-FP-NEXT: add a0, sp, a0
+; OMIT-FP-NEXT: addi a0, a0, 16
+; OMIT-FP-NEXT: vs2r.v v2, (a0) # Unknown-size Folded Spill
+; OMIT-FP-NEXT: addi a0, sp, 16
+; OMIT-FP-NEXT: vs4r.v v4, (a0) # Unknown-size Folded Spill
+; OMIT-FP-NEXT: .cfi_escape 0x10, 0x61, 0x08, 0x11, 0x7e, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # $v1 @ cfa - 2 * vlenb
+; OMIT-FP-NEXT: .cfi_escape 0x10, 0x62, 0x08, 0x11, 0x7c, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # $v2m2 @ cfa - 4 * vlenb
+; OMIT-FP-NEXT: .cfi_escape 0x10, 0x64, 0x08, 0x11, 0x78, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # $v4m4 @ cfa - 8 * vlenb
+; OMIT-FP-NEXT: #APP
+; OMIT-FP-NEXT: #NO_APP
+; OMIT-FP-NEXT: csrr a0, vlenb
+; OMIT-FP-NEXT: li a1, 6
+; OMIT-FP-NEXT: mul a0, a0, a1
+; OMIT-FP-NEXT: add a0, sp, a0
+; OMIT-FP-NEXT: addi a0, a0, 16
+; OMIT-FP-NEXT: vl1r.v v1, (a0) # Unknown-size Folded Reload
+; OMIT-FP-NEXT: csrr a0, vlenb
+; OMIT-FP-NEXT: slli a0, a0, 2
+; OMIT-FP-NEXT: add a0, sp, a0
+; OMIT-FP-NEXT: addi a0, a0, 16
+; OMIT-FP-NEXT: vl2r.v v2, (a0) # Unknown-size Folded Reload
+; OMIT-FP-NEXT: addi a0, sp, 16
+; OMIT-FP-NEXT: vl4r.v v4, (a0) # Unknown-size Folded Reload
+; OMIT-FP-NEXT: csrr a0, vlenb
+; OMIT-FP-NEXT: slli a0, a0, 3
+; OMIT-FP-NEXT: add sp, sp, a0
+; OMIT-FP-NEXT: addi sp, sp, 16
+; OMIT-FP-NEXT: ret
+;
+; NO-OMIT-FP-LABEL: test_vector_callee_cfi:
+; NO-OMIT-FP: # %bb.0: # %entry
+; NO-OMIT-FP-NEXT: addi sp, sp, -32
+; NO-OMIT-FP-NEXT: .cfi_def_cfa_offset 32
+; NO-OMIT-FP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; NO-OMIT-FP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; NO-OMIT-FP-NEXT: .cfi_offset ra, -8
+; NO-OMIT-FP-NEXT: .cfi_offset s0, -16
+; NO-OMIT-FP-NEXT: addi s0, sp, 32
+; NO-OMIT-FP-NEXT: .cfi_def_cfa s0, 0
+; NO-OMIT-FP-NEXT: csrr a0, vlenb
+; NO-OMIT-FP-NEXT: slli a0, a0, 3
+; NO-OMIT-FP-NEXT: sub sp, sp, a0
+; NO-OMIT-FP-NEXT: csrr a0, vlenb
+; NO-OMIT-FP-NEXT: slli a0, a0, 1
+; NO-OMIT-FP-NEXT: sub a0, s0, a0
+; NO-OMIT-FP-NEXT: addi a0, a0, -32
+; NO-OMIT-FP-NEXT: vs1r.v v1, (a0) # Unknown-size Folded Spill
+; NO-OMIT-FP-NEXT: csrr a0, vlenb
+; NO-OMIT-FP-NEXT: slli a0, a0, 2
+; NO-OMIT-FP-NEXT: sub a0, s0, a0
+; NO-OMIT-FP-NEXT: addi a0, a0, -32
+; NO-OMIT-FP-NEXT: vs2r.v v2, (a0) # Unknown-size Folded Spill
+; NO-OMIT-FP-NEXT: csrr a0, vlenb
+; NO-OMIT-FP-NEXT: slli a0, a0, 3
+; NO-OMIT-FP-NEXT: sub a0, s0, a0
+; NO-OMIT-FP-NEXT: addi a0, a0, -32
+; NO-OMIT-FP-NEXT: vs4r.v v4, (a0) # Unknown-size Folded Spill
+; NO-OMIT-FP-NEXT: .cfi_escape 0x10, 0x61, 0x0b, 0x11, 0x60, 0x22, 0x11, 0x7e, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # $v1 @ cfa - 32 - 2 * vlenb
+; NO-OMIT-FP-NEXT: .cfi_escape 0x10, 0x62, 0x0b, 0x11, 0x60, 0x22, 0x11, 0x7c, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # $v2m2 @ cfa - 32 - 4 * vlenb
+; NO-OMIT-FP-NEXT: .cfi_escape 0x10, 0x64, 0x0b, 0x11, 0x60, 0x22, 0x11, 0x78, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # $v4m4 @ cfa - 32 - 8 * vlenb
+; NO-OMIT-FP-NEXT: #APP
+; NO-OMIT-FP-NEXT: #NO_APP
+; NO-OMIT-FP-NEXT: csrr a0, vlenb
+; NO-OMIT-FP-NEXT: slli a0, a0, 1
+; NO-OMIT-FP-NEXT: sub a0, s0, a0
+; NO-OMIT-FP-NEXT: addi a0, a0, -32
+; NO-OMIT-FP-NEXT: vl1r.v v1, (a0) # Unknown-size Folded Reload
+; NO-OMIT-FP-NEXT: csrr a0, vlenb
+; NO-OMIT-FP-NEXT: slli a0, a0, 2
+; NO-OMIT-FP-NEXT: sub a0, s0, a0
+; NO-OMIT-FP-NEXT: addi a0, a0, -32
+; NO-OMIT-FP-NEXT: vl2r.v v2, (a0) # Unknown-size Folded Reload
+; NO-OMIT-FP-NEXT: csrr a0, vlenb
+; NO-OMIT-FP-NEXT: slli a0, a0, 3
+; NO-OMIT-FP-NEXT: sub a0, s0, a0
+; NO-OMIT-FP-NEXT: addi a0, a0, -32
+; NO-OMIT-FP-NEXT: vl4r.v v4, (a0) # Unknown-size Folded Reload
+; NO-OMIT-FP-NEXT: addi sp, s0, -32
+; NO-OMIT-FP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; NO-OMIT-FP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; NO-OMIT-FP-NEXT: addi sp, sp, 32
+; NO-OMIT-FP-NEXT: ret
+entry:
+ call void asm sideeffect "",
+ "~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7}"()
+
+ ret <vscale x 1 x i32> %va
+}
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll
index 1d3c22a02efc0f..ab6df1d3e883fd 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll
@@ -628,6 +628,7 @@ define void @insert_v2i64_nxv16i64_hi(ptr %psv, ptr %out) {
; RV32-NEXT: vs8r.v v8, (a0)
; RV32-NEXT: vs8r.v v16, (a1)
; RV32-NEXT: addi sp, s0, -80
+; RV32-NEXT: .cfi_def_cfa sp, 80
; RV32-NEXT: lw ra, 76(sp) # 4-byte Folded Reload
; RV32-NEXT: lw s0, 72(sp) # 4-byte Folded Reload
; RV32-NEXT: addi sp, sp, 80
@@ -661,6 +662,7 @@ define void @insert_v2i64_nxv16i64_hi(ptr %psv, ptr %out) {
; RV64-NEXT: vs8r.v v8, (a0)
; RV64-NEXT: vs8r.v v16, (a1)
; RV64-NEXT: addi sp, s0, -80
+; RV64-NEXT: .cfi_def_cfa sp, 80
; RV64-NEXT: ld ra, 72(sp) # 8-byte Folded Reload
; RV64-NEXT: ld s0, 64(sp) # 8-byte Folded Reload
; RV64-NEXT: addi sp, sp, 80
More information about the llvm-commits
mailing list