[PATCH] Fix AArch64 prologue for empty frame with dynamic allocas

Evgeniy Stepanov eugenis at google.com
Tue Jun 30 15:53:09 PDT 2015


PTAL


http://reviews.llvm.org/D10826

Files:
  lib/Target/AArch64/AArch64FrameLowering.cpp
  test/CodeGen/AArch64/aarch64-dynamic-stack-layout-pr23804.ll

Index: lib/Target/AArch64/AArch64FrameLowering.cpp
===================================================================
--- lib/Target/AArch64/AArch64FrameLowering.cpp
+++ lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -351,11 +351,15 @@
   const unsigned Alignment = MFI->getMaxAlignment();
   const bool NeedsRealignment = (Alignment > 16);
   unsigned scratchSPReg = AArch64::SP;
-  if (NeedsRealignment) {
+  if (NumBytes && NeedsRealignment) {
     // Use the first callee-saved register as a scratch register
-    assert(MF.getRegInfo().isPhysRegUsed(AArch64::X9) &&
-           "No scratch register to align SP!");
-    scratchSPReg = AArch64::X9;
+    if (MF.getRegInfo().isPhysRegUsed(AArch64::X9)) {
+      scratchSPReg = AArch64::X9;
+    } else if (RegInfo->hasBasePointer(MF)) {
+      scratchSPReg = RegInfo->getBaseRegister();
+    } else {
+      report_fatal_error("No scratch register to align SP!");
+    }
   }
 
   // If we're a leaf function, try using the red zone.
@@ -366,9 +370,6 @@
     emitFrameOffset(MBB, MBBI, DL, scratchSPReg, AArch64::SP, -NumBytes, TII,
                     MachineInstr::FrameSetup);
 
-  assert(!(NeedsRealignment && NumBytes==0) &&
-         "NumBytes should never be 0 when realignment is needed");
-
   if (NumBytes && NeedsRealignment) {
     const unsigned NrBitsToZero = countTrailingZeros(Alignment);
     assert(NrBitsToZero > 1);
Index: test/CodeGen/AArch64/aarch64-dynamic-stack-layout-pr23804.ll
===================================================================
--- test/CodeGen/AArch64/aarch64-dynamic-stack-layout-pr23804.ll
+++ test/CodeGen/AArch64/aarch64-dynamic-stack-layout-pr23804.ll
@@ -0,0 +1,52 @@
+; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s
+
+define void @realign_conditional(i1 %b) {
+entry:
+  br i1 %b, label %bb0, label %bb1
+
+bb0:
+  %MyAlloca = alloca i8, i64 64, align 32
+  br label %bb1
+
+bb1:
+  ret void
+}
+
+; CHECK-LABEL: realign_conditional
+; No realignment in the prologue.
+; CHECK-NOT:  and
+; CHECK-NOT:  0xffffffffffffffe0
+; CHECK:  tbz  {{.*}} .[[LABEL:.*]]
+; Stack is realigned in a non-entry BB.
+; CHECK:  sub  [[REG:x[01-9]+]], sp, #64
+; CHECK:  and  sp, [[REG]], #0xffffffffffffffe0
+; CHECK:  .[[LABEL]]:
+; CHECK:  ret
+
+
+define void @realign_conditional2(i1 %b) {
+entry:
+  %tmp = alloca i8, i32 4
+  br i1 %b, label %bb0, label %bb1
+
+bb0:
+  %MyAlloca = alloca i8, i64 64, align 32
+  br label %bb1
+
+bb1:
+  ret void
+}
+
+; CHECK-LABEL: realign_conditional2
+; Extra realignment in the prologue (performance issue).
+; X19 is used as a scratch register for SP realignment before it is assigned the
+; base pointer.
+; CHECK:  sub  x19, sp, #32            // =32
+; CHECK:  and  sp, x19, #0xffffffffffffffe0
+; CHECK:  mov   x19, sp
+; CHECK:  tbz  {{.*}} .[[LABEL:.*]]
+; Stack is realigned in a non-entry BB.
+; CHECK:  sub  [[REG:x[01-9]+]], sp, #64
+; CHECK:  and  sp, [[REG]], #0xffffffffffffffe0
+; CHECK:  .[[LABEL]]:
+; CHECK:  ret

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D10826.28822.patch
Type: text/x-patch
Size: 3003 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150630/b83954f1/attachment.bin>


More information about the llvm-commits mailing list