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