Do not change the type of a ByVal argument to a
authorDale Johannesen <dalej@apple.com>
Wed, 23 Apr 2008 01:03:05 +0000 (01:03 +0000)
committerDale Johannesen <dalej@apple.com>
Wed, 23 Apr 2008 01:03:05 +0000 (01:03 +0000)
type of a different size.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50121 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index c2019389baeec7b5f9cad5075515d2e32b66fc51..c2f4545e4b36b5b51117f2212b839452c338ad12 100644 (file)
@@ -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;
         }
       }