[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