forked from OSchip/llvm-project
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:
parent
05747f3734
commit
82a46ebe0a
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue