[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