Fixed a bug in dynamic allocation memory on stack.

The alignment of allocated space was wrong, see Bugzila 17345.

Done by Zvi Rackover <zvi.rackover@intel.com>.

llvm-svn: 192573
This commit is contained in:
Elena Demikhovsky 2013-10-14 07:26:51 +00:00
parent 05747f3734
commit 82a46ebe0a
5 changed files with 77 additions and 11 deletions

View File

@ -1581,10 +1581,10 @@ void SelectionDAGLegalize::ExpandDYNAMIC_STACKALLOC(SDNode* Node,
Chain = SP.getValue(1);
unsigned Align = cast<ConstantSDNode>(Tmp3)->getZExtValue();
unsigned StackAlign = TM.getFrameLowering()->getStackAlignment();
if (Align > StackAlign)
SP = DAG.getNode(ISD::AND, dl, VT, SP,
DAG.getConstant(-(uint64_t)Align, VT));
Tmp1 = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value
if (Align > StackAlign)
Tmp1 = DAG.getNode(ISD::AND, dl, VT, Tmp1,
DAG.getConstant(-(uint64_t)Align, VT));
Chain = DAG.getCopyToReg(Chain, dl, SPReg, Tmp1); // Output chain
Tmp2 = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, true),

View File

@ -10755,7 +10755,8 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
// Get the inputs.
SDValue Chain = Op.getOperand(0);
SDValue Size = Op.getOperand(1);
// FIXME: Ensure alignment here
unsigned Align = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue();
EVT VT = Op.getNode()->getValueType(0);
bool Is64Bit = Subtarget->is64Bit();
EVT SPTy = Is64Bit ? MVT::i64 : MVT::i32;
@ -10793,14 +10794,20 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
Chain = DAG.getNode(X86ISD::WIN_ALLOCA, dl, NodeTys, Chain, Flag);
Flag = Chain.getValue(1);
const X86RegisterInfo *RegInfo =
static_cast<const X86RegisterInfo*>(getTargetMachine().getRegisterInfo());
Chain = DAG.getCopyFromReg(Chain, dl, RegInfo->getStackRegister(),
SPTy).getValue(1);
unsigned SPReg = RegInfo->getStackRegister();
SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, SPTy);
Chain = SP.getValue(1);
SDValue Ops1[2] = { Chain.getValue(0), Chain };
if (Align) {
SP = DAG.getNode(ISD::AND, dl, VT, SP.getValue(0),
DAG.getConstant(-(uint64_t)Align, VT));
Chain = DAG.getCopyToReg(Chain, dl, SPReg, SP);
}
SDValue Ops1[2] = { SP, Chain };
return DAG.getMergeValues(Ops1, 2, dl);
}
}

View File

@ -8,10 +8,10 @@ define void @t() nounwind ssp {
entry:
; CHECK-LABEL: t:
%size = mul i32 8, 2
; CHECK: subs r0, #16
; CHECK: sub.w r0, sp, #16
; CHECK: mov sp, r0
%vla_a = alloca i8, i32 %size, align 8
; CHECK: subs r0, #16
; CHECK: sub.w r0, sp, #16
; CHECK: mov sp, r0
%vla_b = alloca i8, i32 %size, align 8
unreachable

View File

@ -0,0 +1,9 @@
; RUN: llc -mtriple=x86_64-linux < %s | FileCheck %s
define i32 @A(i32 %Size) {
; CHECK: subq %rcx, %rax
; CHECK: andq $-128, %rax
; CHECK: movq %rax, %rsp
%A = alloca i8, i32 %Size, align 128
%A_addr = ptrtoint i8* %A to i32
ret i32 %A_addr
}

View File

@ -4,7 +4,10 @@
; PR8777
; PR8778
define i64 @foo(i64 %n, i64 %x) nounwind {
define i64 @unaligned(i64 %n, i64 %x) nounwind {
; M64-LABEL: unaligned:
; W64-LABEL: unaligned:
; EFI-LABEL: unaligned:
entry:
%buf0 = alloca i8, i64 4096, align 1
@ -71,4 +74,51 @@ entry:
}
define i64 @aligned(i64 %n, i64 %x) nounwind {
; M64-LABEL: aligned:
; W64-LABEL: aligned:
; EFI-LABEL: aligned:
entry:
%buf1 = alloca i8, i64 %n, align 128
; M64: leaq 15(%{{.*}}), %rax
; M64: andq $-16, %rax
; M64: callq ___chkstk
; M64: movq %rsp, [[R2:%r.*]]
; M64: andq $-128, [[R2]]
; M64: movq [[R2]], %rsp
; W64: leaq 15(%{{.*}}), %rax
; W64: andq $-16, %rax
; W64: callq __chkstk
; W64: subq %rax, %rsp
; W64: movq %rsp, [[R2:%r.*]]
; W64: andq $-128, [[R2]]
; W64: movq [[R2]], %rsp
; EFI: leaq 15(%{{.*}}), [[R1:%r.*]]
; EFI: andq $-16, [[R1]]
; EFI: movq %rsp, [[R64:%r.*]]
; EFI: subq [[R1]], [[R64]]
; EFI: andq $-128, [[R64]]
; EFI: movq [[R64]], %rsp
%r = call i64 @bar(i64 %n, i64 %x, i64 %n, i8* undef, i8* %buf1) nounwind
; M64: subq $48, %rsp
; M64: movq [[R2]], 32(%rsp)
; M64: callq bar
; W64: subq $48, %rsp
; W64: movq [[R2]], 32(%rsp)
; W64: callq bar
; EFI: subq $48, %rsp
; EFI: movq [[R64]], 32(%rsp)
; EFI: callq _bar
ret i64 %r
}
declare i64 @bar(i64, i64, i64, i8* nocapture, i8* nocapture) nounwind