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),
// 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;
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);
+
+ 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] = { Chain.getValue(0), Chain };
+ SDValue Ops1[2] = { SP, Chain };
return DAG.getMergeValues(Ops1, 2, dl);
}
}
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
--- /dev/null
+; 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
+}
; 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
}
+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