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
This commit is contained in:
Evgeniy Stepanov 2015-07-10 21:24:07 +00:00
parent 020938f3ee
commit 61b8d4a9df
2 changed files with 54 additions and 8 deletions

View File

@ -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);

View File

@ -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" }