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 | 493527d8c9421a1da2c523914047ef78d5ed8302 (patch) | |
tree | 3ce66f4c2be650182e60bcf6e5881f4607ee2ca4 /llvm/lib/Transforms | |
parent | ef9af73887895fa273a0df921a7434290d45ac5d (diff) | |
download | bcm5719-llvm-493527d8c9421a1da2c523914047ef78d5ed8302.tar.gz bcm5719-llvm-493527d8c9421a1da2c523914047ef78d5ed8302.zip |
Do not change the type of a ByVal argument to a
type of a different size.
llvm-svn: 50121
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index c2019389bae..c2f4545e4b3 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/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; } } |