diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index 0dbc35b2248d..855f9a443b75 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -2763,6 +2763,13 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) { I.getAlignment()); SDValue AllocSize = getValue(I.getArraySize()); + + AllocSize = DAG.getNode(ISD::MUL, getCurDebugLoc(), AllocSize.getValueType(), + AllocSize, + DAG.getConstant(TySize, AllocSize.getValueType())); + + + MVT IntPtr = TLI.getPointerTy(); if (IntPtr.bitsLT(AllocSize.getValueType())) AllocSize = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), @@ -2771,9 +2778,6 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) { AllocSize = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), IntPtr, AllocSize); - AllocSize = DAG.getNode(ISD::MUL, getCurDebugLoc(), IntPtr, AllocSize, - DAG.getIntPtrConstant(TySize)); - // Handle alignment. If the requested alignment is less than or equal to // the stack alignment, ignore it. If the size is greater than or equal to // the stack alignment, we note this in the DYNAMIC_STACKALLOC node. @@ -5425,6 +5429,16 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { void SelectionDAGLowering::visitMalloc(MallocInst &I) { SDValue Src = getValue(I.getOperand(0)); + // Scale up by the type size in the original i32 type width. Various + // mid-level optimizers may make assumptions about demanded bits etc from the + // i32-ness of the optimizer: we do not want to promote to i64 and then + // multiply on 64-bit targets. + // FIXME: Malloc inst should go away: PR715. + uint64_t ElementSize = TD->getTypePaddedSize(I.getType()->getElementType()); + if (ElementSize != 1) + Src = DAG.getNode(ISD::MUL, getCurDebugLoc(), Src.getValueType(), + Src, DAG.getConstant(ElementSize, Src.getValueType())); + MVT IntPtr = TLI.getPointerTy(); if (IntPtr.bitsLT(Src.getValueType())) @@ -5432,11 +5446,6 @@ void SelectionDAGLowering::visitMalloc(MallocInst &I) { else if (IntPtr.bitsGT(Src.getValueType())) Src = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), IntPtr, Src); - // Scale the source by the type size. - uint64_t ElementSize = TD->getTypePaddedSize(I.getType()->getElementType()); - Src = DAG.getNode(ISD::MUL, getCurDebugLoc(), Src.getValueType(), - Src, DAG.getIntPtrConstant(ElementSize)); - TargetLowering::ArgListTy Args; TargetLowering::ArgListEntry Entry; Entry.Node = Src; diff --git a/llvm/test/CodeGen/X86/x86-64-malloc.ll b/llvm/test/CodeGen/X86/x86-64-malloc.ll new file mode 100644 index 000000000000..4beb5c21acab --- /dev/null +++ b/llvm/test/CodeGen/X86/x86-64-malloc.ll @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | llc -march=x86-64 | grep {shll.*3, %edi} +; PR3829 +; The generated code should multiply by 3 (sizeof i8*) as an i32, +; not as an i64! + +define i8** @test(i32 %sz) { + %sub = add i32 %sz, 536870911 ; [#uses=1] + %call = malloc i8*, i32 %sub ; [#uses=1] + ret i8** %call +}