[llvm] Prefer bic insread of lsl/lsr to align stack where possible (PR #82123)

via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 17 10:43:15 PST 2024


https://github.com/AtariDreams created https://github.com/llvm/llvm-project/pull/82123

We can use bic to align the stack pointer if we can encode an immediate in there.

Otherwise, fallback to the shifts.

>From 1a3a4e0ac045f54a9c4a96aa095995873d07fc5d Mon Sep 17 00:00:00 2001
From: Rose <83477269+AtariDreams at users.noreply.github.com>
Date: Sat, 17 Feb 2024 13:39:43 -0500
Subject: [PATCH] Prefer bic insread of lsl/lsr to align stack where possible

We can use bic to align the stack pointer if we can encode an immediate in there.

Otherwise, fallback to the shifts.
---
 llvm/lib/Target/ARM/Thumb1FrameLowering.cpp | 75 ++++++++++++++-------
 1 file changed, 49 insertions(+), 26 deletions(-)

diff --git a/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp b/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
index 0f4ece64bff532..1e17d9928526e5 100644
--- a/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
+++ b/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp
@@ -448,32 +448,55 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF,
   AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
 
   if (RegInfo->hasStackRealignment(MF)) {
-    const unsigned NrBitsToZero = Log2(MFI.getMaxAlign());
-    // Emit the following sequence, using R4 as a temporary, since we cannot use
-    // SP as a source or destination register for the shifts:
-    // mov  r4, sp
-    // lsrs r4, r4, #NrBitsToZero
-    // lsls r4, r4, #NrBitsToZero
-    // mov  sp, r4
-    BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::R4)
-      .addReg(ARM::SP, RegState::Kill)
-      .add(predOps(ARMCC::AL));
-
-    BuildMI(MBB, MBBI, dl, TII.get(ARM::tLSRri), ARM::R4)
-      .addDef(ARM::CPSR)
-      .addReg(ARM::R4, RegState::Kill)
-      .addImm(NrBitsToZero)
-      .add(predOps(ARMCC::AL));
-
-    BuildMI(MBB, MBBI, dl, TII.get(ARM::tLSLri), ARM::R4)
-      .addDef(ARM::CPSR)
-      .addReg(ARM::R4, RegState::Kill)
-      .addImm(NrBitsToZero)
-      .add(predOps(ARMCC::AL));
-
-    BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::SP)
-      .addReg(ARM::R4, RegState::Kill)
-      .add(predOps(ARMCC::AL));
+    const Align Alignment = MFI.getMaxAlign();
+    const unsigned NrBitsToZero = Log2(Alignment);
+    const unsigned AlignMask = Alignment.value() - 1U;
+
+    // Emit the following sequence, using R4 as a temporary, since we cannot
+    // use SP as a source or destination register:
+    //   mov r4, sp
+    //
+    // Then, if the mask to zero the required number of bits
+    // can be encoded in the bic immediate field:
+    //   bic r4, r4, Alignment-1
+    // otherwise, emit:
+    //   lsr r4, r4, log2(Alignment)
+    //   lsl r4, r4, log2(Alignment)
+    //
+    // Finally, save back to sp:
+    //   mov sp, r4
+    if (AlignMask <= 255) {
+      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::R4)
+          .addReg(ARM::SP, RegState::Kill)
+          .add(predOps(ARMCC::AL));
+      BuildMI(MBB, MBBI, dl, TII.get(ARM::tBIC), ARM::R4)
+          .addReg(ARM::R4, RegState::Kill)
+          .addImm(AlignMask)
+          .add(predOps(ARMCC::AL));
+      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::SP)
+          .addReg(ARM::R4, RegState::Kill)
+          .add(predOps(ARMCC::AL));
+    } else {
+      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::R4)
+          .addReg(ARM::SP, RegState::Kill)
+          .add(predOps(ARMCC::AL));
+
+      BuildMI(MBB, MBBI, dl, TII.get(ARM::tLSRri), ARM::R4)
+          .addDef(ARM::CPSR)
+          .addReg(ARM::R4, RegState::Kill)
+          .addImm(NrBitsToZero)
+          .add(predOps(ARMCC::AL));
+
+      BuildMI(MBB, MBBI, dl, TII.get(ARM::tLSLri), ARM::R4)
+          .addDef(ARM::CPSR)
+          .addReg(ARM::R4, RegState::Kill)
+          .addImm(NrBitsToZero)
+          .add(predOps(ARMCC::AL));
+
+      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::SP)
+          .addReg(ARM::R4, RegState::Kill)
+          .add(predOps(ARMCC::AL));
+    }
 
     AFI->setShouldRestoreSPFromFP(true);
   }



More information about the llvm-commits mailing list