From: Evgeniy Stepanov Date: Fri, 10 Jul 2015 21:24:07 +0000 (+0000) Subject: Fix AArch64 prologue for empty frame with dynamic allocas. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=61b8d4a9df1c927d2c021f7a42e6f60c96474eab;p=oota-llvm.git Fix AArch64 prologue for empty frame with dynamic allocas. Fixes PR23804: assertion failure in emitPrologue in the case of a function with an empty frame and a dynamic alloca that needs stack realignment. This is a typical case for AddressSanitizer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241943 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AArch64/AArch64FrameLowering.cpp b/lib/Target/AArch64/AArch64FrameLowering.cpp index 3ba7e70a102..2e552cd300b 100644 --- a/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -349,13 +349,12 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF, // Allocate space for the rest of the frame. const unsigned Alignment = MFI->getMaxAlignment(); - const bool NeedsRealignment = (Alignment > 16); + const bool NeedsRealignment = RegInfo->needsStackRealignment(MF); unsigned scratchSPReg = AArch64::SP; - if (NeedsRealignment) { - // Use the first callee-saved register as a scratch register - assert(MF.getRegInfo().isPhysRegUsed(AArch64::X9) && - "No scratch register to align SP!"); + if (NumBytes && NeedsRealignment) { + // Use the first callee-saved register as a scratch register. scratchSPReg = AArch64::X9; + MF.getRegInfo().setPhysRegUsed(scratchSPReg); } // If we're a leaf function, try using the red zone. @@ -366,9 +365,6 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF, 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); diff --git a/test/CodeGen/AArch64/aarch64-dynamic-stack-layout.ll b/test/CodeGen/AArch64/aarch64-dynamic-stack-layout.ll index f33211eadd2..739570236da 100644 --- a/test/CodeGen/AArch64/aarch64-dynamic-stack-layout.ll +++ b/test/CodeGen/AArch64/aarch64-dynamic-stack-layout.ll @@ -482,6 +482,56 @@ entry: ; CHECK: ldp x20, x19, [sp], #32 ; CHECK: ret + +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). +; CHECK: sub x9, sp, #32 // =32 +; CHECK: and sp, x9, #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 + attributes #0 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }