From 63e7eb4e129e838ae71b06803dda297e8d314714 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Wed, 23 Apr 2008 01:03:05 +0000 Subject: [PATCH] Do not change the type of a ByVal argument to a type of a different size. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50121 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index c2019389bae..c2f4545e4b3 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -8748,16 +8748,29 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) { const PointerType *PTy = cast(Callee->getType()); const FunctionType *FTy = cast(PTy->getElementType()); if (FTy->isVarArg()) { + int ix = FTy->getNumParams() + (isa(Callee) ? 3 : 1); // See if we can optimize any arguments passed through the varargs area of // the call. for (CallSite::arg_iterator I = CS.arg_begin()+FTy->getNumParams(), - E = CS.arg_end(); I != E; ++I) + E = CS.arg_end(); I != E; ++I, ++ix) if (CastInst *CI = dyn_cast(*I)) { - // If this cast does not effect the value passed through the varargs + // If this cast does not affect the value passed through the varargs // area, we can eliminate the use of the cast. - Value *Op = CI->getOperand(0); + const PointerType* SrcPTy, *DstPTy; if (CI->isLosslessCast()) { - *I = Op; + // The size of ByVal arguments is derived from the type, so we + // can't change to a type with a different size. If the size were + // passed explicitly we could avoid this check. + if (CS.paramHasAttr(ix, ParamAttr::ByVal) && + (SrcPTy = cast(CI->getOperand(0)->getType())) && + (DstPTy = cast(CI->getType()))) { + const Type* SrcTy = SrcPTy->getElementType(); + const Type* DstTy = DstPTy->getElementType(); + if (!SrcTy->isSized() || !DstTy->isSized() || + TD->getABITypeSize(SrcTy) != TD->getABITypeSize(DstTy)) + continue; + } + *I = CI->getOperand(0); Changed = true; } }