[llvm] [LoongArch] Revert `sp` adjustment in prologue (PR #88110)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 9 04:29:18 PDT 2024
https://github.com/heiher created https://github.com/llvm/llvm-project/pull/88110
After commit 18c5f3c3 ("[RegisterScavenger][RISCV] Don't search for FrameSetup instrs if we were searching from Non-FrameSetup instrs"), we can revert the `sp` adjustment to generate better code, as the issue with `RegScavenger` has been resolved.
Fixes #88109
>From 8a180233335d0a061dd0f946ae01abade60301f0 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Tue, 9 Apr 2024 19:12:43 +0800
Subject: [PATCH] [LoongArch] Revert `sp` adjustment in prologue
After commit 18c5f3c3 ("[RegisterScavenger][RISCV] Don't search for FrameSetup
instrs if we were searching from Non-FrameSetup instrs"), we can revert the `sp`
adjustment to generate better code, as the issue with `RegScavenger` has been
resolved.
Fixes #88109
---
.../LoongArch/LoongArchFrameLowering.cpp | 55 ++++++-------------
.../Target/LoongArch/LoongArchFrameLowering.h | 3 +-
.../CodeGen/LoongArch/emergency-spill-slot.ll | 6 +-
3 files changed, 21 insertions(+), 43 deletions(-)
diff --git a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp
index dc2d61a6e4740e..330c15958f4f27 100644
--- a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp
@@ -206,22 +206,19 @@ void LoongArchFrameLowering::emitPrologue(MachineFunction &MF,
if (StackSize == 0 && !MFI.adjustsStack())
return;
- uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF, true);
- uint64_t SecondSPAdjustAmount = RealStackSize - FirstSPAdjustAmount;
+ uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
// Split the SP adjustment to reduce the offsets of callee saved spill.
if (FirstSPAdjustAmount)
StackSize = FirstSPAdjustAmount;
// Adjust stack.
adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, MachineInstr::FrameSetup);
- if (FirstSPAdjustAmount != 2048 || SecondSPAdjustAmount == 0) {
- // Emit ".cfi_def_cfa_offset StackSize".
- unsigned CFIIndex =
- MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize));
- BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
- .addCFIIndex(CFIIndex)
- .setMIFlag(MachineInstr::FrameSetup);
- }
+ // Emit ".cfi_def_cfa_offset StackSize".
+ unsigned CFIIndex =
+ MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize));
+ BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameSetup);
const auto &CSI = MFI.getCalleeSavedInfo();
@@ -258,25 +255,14 @@ void LoongArchFrameLowering::emitPrologue(MachineFunction &MF,
}
// Emit the second SP adjustment after saving callee saved registers.
- if (FirstSPAdjustAmount && SecondSPAdjustAmount) {
- if (hasFP(MF)) {
- assert(SecondSPAdjustAmount > 0 &&
- "SecondSPAdjustAmount should be greater than zero");
- adjustReg(MBB, MBBI, DL, SPReg, SPReg, -SecondSPAdjustAmount,
- MachineInstr::FrameSetup);
- } else {
- // FIXME: RegScavenger will place the spill instruction before the
- // prologue if a VReg is created in the prologue. This will pollute the
- // caller's stack data. Therefore, until there is better way, we just use
- // the `addi.w/d` instruction for stack adjustment to ensure that VReg
- // will not be created.
- for (int Val = SecondSPAdjustAmount; Val > 0; Val -= 2048)
- BuildMI(MBB, MBBI, DL,
- TII->get(IsLA64 ? LoongArch::ADDI_D : LoongArch::ADDI_W), SPReg)
- .addReg(SPReg)
- .addImm(Val < 2048 ? -Val : -2048)
- .setMIFlag(MachineInstr::FrameSetup);
+ if (FirstSPAdjustAmount) {
+ uint64_t SecondSPAdjustAmount = RealStackSize - FirstSPAdjustAmount;
+ assert(SecondSPAdjustAmount > 0 &&
+ "SecondSPAdjustAmount should be greater than zero");
+ adjustReg(MBB, MBBI, DL, SPReg, SPReg, -SecondSPAdjustAmount,
+ MachineInstr::FrameSetup);
+ if (!hasFP(MF)) {
// If we are using a frame-pointer, and thus emitted ".cfi_def_cfa fp, 0",
// don't emit an sp-based .cfi_def_cfa_offset
// Emit ".cfi_def_cfa_offset RealStackSize"
@@ -370,26 +356,19 @@ void LoongArchFrameLowering::emitEpilogue(MachineFunction &MF,
// st.d $fp, $sp, 2016
// addi.d $sp, $sp, -16
uint64_t
-LoongArchFrameLowering::getFirstSPAdjustAmount(const MachineFunction &MF,
- bool IsPrologue) const {
+LoongArchFrameLowering::getFirstSPAdjustAmount(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
// Return the FirstSPAdjustAmount if the StackSize can not fit in a signed
// 12-bit and there exists a callee-saved register needing to be pushed.
- if (!isInt<12>(MFI.getStackSize())) {
+ if (!isInt<12>(MFI.getStackSize()) && (CSI.size() > 0)) {
// FirstSPAdjustAmount is chosen as (2048 - StackAlign) because 2048 will
// cause sp = sp + 2048 in the epilogue to be split into multiple
// instructions. Offsets smaller than 2048 can fit in a single load/store
// instruction, and we have to stick with the stack alignment.
// So (2048 - StackAlign) will satisfy the stack alignment.
- //
- // FIXME: This place may seem odd. When using multiple ADDI instructions to
- // adjust the stack in Prologue, and there are no callee-saved registers, we
- // can take advantage of the logic of split sp ajustment to reduce code
- // changes.
- return CSI.size() > 0 ? 2048 - getStackAlign().value()
- : (IsPrologue ? 2048 : 0);
+ return 2048 - getStackAlign().value();
}
return 0;
}
diff --git a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h
index 57d2565c32c094..bc2ac02c91f814 100644
--- a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h
@@ -52,8 +52,7 @@ class LoongArchFrameLowering : public TargetFrameLowering {
bool hasFP(const MachineFunction &MF) const override;
bool hasBP(const MachineFunction &MF) const;
- uint64_t getFirstSPAdjustAmount(const MachineFunction &MF,
- bool IsPrologue = false) const;
+ uint64_t getFirstSPAdjustAmount(const MachineFunction &MF) const;
bool enableShrinkWrapping(const MachineFunction &MF) const override;
diff --git a/llvm/test/CodeGen/LoongArch/emergency-spill-slot.ll b/llvm/test/CodeGen/LoongArch/emergency-spill-slot.ll
index 08426b07bf74ba..4565c63f08d995 100644
--- a/llvm/test/CodeGen/LoongArch/emergency-spill-slot.ll
+++ b/llvm/test/CodeGen/LoongArch/emergency-spill-slot.ll
@@ -6,9 +6,9 @@
define void @func() {
; CHECK-LABEL: func:
; CHECK: # %bb.0:
-; CHECK-NEXT: addi.d $sp, $sp, -2048
-; CHECK-NEXT: addi.d $sp, $sp, -2048
-; CHECK-NEXT: addi.d $sp, $sp, -16
+; CHECK-NEXT: lu12i.w $a0, 1
+; CHECK-NEXT: ori $a0, $a0, 16
+; CHECK-NEXT: sub.d $sp, $sp, $a0
; CHECK-NEXT: .cfi_def_cfa_offset 4112
; CHECK-NEXT: pcalau12i $a0, %got_pc_hi20(var)
; CHECK-NEXT: ld.d $a1, $a0, %got_pc_lo12(var)
More information about the llvm-commits
mailing list