summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2008-04-23 01:03:05 +0000
committerDale Johannesen <dalej@apple.com>2008-04-23 01:03:05 +0000
commit493527d8c9421a1da2c523914047ef78d5ed8302 (patch)
tree3ce66f4c2be650182e60bcf6e5881f4607ee2ca4 /llvm/lib/Transforms
parentef9af73887895fa273a0df921a7434290d45ac5d (diff)
downloadbcm5719-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.cpp21
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;
}
}
OpenPOWER on IntegriCloud