diff options
author | Dale Johannesen <dalej@apple.com> | 2008-04-23 01:03:05 +0000 |
---|---|---|
committer | Dale Johannesen <dalej@apple.com> | 2008-04-23 01:03:05 +0000 |
commit | 63e7eb4e129e838ae71b06803dda297e8d314714 (patch) | |
tree | e07e3d6c576d386c23b8e23074e63b873451efd0 | |
parent | f30752cbcc9a29bc10f1d811bdfe2c78f267e51b (diff) |
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
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index c2019389ba..c2f4545e4b 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<PointerType>(Callee->getType()); const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); if (FTy->isVarArg()) { + int ix = FTy->getNumParams() + (isa<InvokeInst>(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<CastInst>(*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<PointerType>(CI->getOperand(0)->getType())) && + (DstPTy = cast<PointerType>(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; } } |