Skip to content

[LoongArch] Revert sp adjustment in prologue #88110

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

Merged
merged 1 commit into from
Apr 10, 2024

Conversation

heiher
Copy link
Member

@heiher heiher commented Apr 9, 2024

After commit 18c5f3c ("[RegisterScavenger][RISCV] Don't search for FrameSetup instrs if we were searching from Non-FrameSetup instrs"), we can revert the sp adjustment 4e2364a ("[LoongArch] Add emergency spill slot for GPR for large frames") to generate better code, as the issue with RegScavenger has been resolved.

Fixes #88109

@heiher heiher requested review from wangleiat and SixWeining April 9, 2024 11:29
@heiher heiher self-assigned this Apr 9, 2024
@llvmbot
Copy link
Member

llvmbot commented Apr 9, 2024

@llvm/pr-subscribers-backend-loongarch

Author: hev (heiher)

Changes

After commit 18c5f3c ("[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


Full diff: https://github.com/llvm/llvm-project/pull/88110.diff

3 Files Affected:

  • (modified) llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp (+17-38)
  • (modified) llvm/lib/Target/LoongArch/LoongArchFrameLowering.h (+1-2)
  • (modified) llvm/test/CodeGen/LoongArch/emergency-spill-slot.ll (+3-3)
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)

Copy link

github-actions bot commented Apr 9, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@heiher heiher force-pushed the revert-sp-adj-in-prologue branch from 8a18023 to 70cd1a8 Compare April 9, 2024 11:35
After commit 18c5f3c ("[RegisterScavenger][RISCV] Don't search for FrameSetup
instrs if we were searching from Non-FrameSetup instrs"), we can revert the `sp`
adjustment 4e2364a ("[LoongArch] Add emergency spill slot for GPR for large
frames") to generate better code, as the issue with `RegScavenger` has been
resolved.

Fixes #88109
Copy link
Contributor

@SixWeining SixWeining left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks.

@heiher heiher merged commit 0d17e1f into llvm:main Apr 10, 2024
@heiher heiher deleted the revert-sp-adj-in-prologue branch April 10, 2024 09:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[LoongArch] Too many sp adjustment instructions in the prologue
3 participants