I noticed that the trampoline straightening transformation could
drop attributes on varargs call arguments.  Also, it could generate
invalid IR if the transformed call already had the 'nest' attribute
somewhere (this can never happen for code coming from llvm-gcc,
but it's a theoretical possibility).  Fix both problems.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45973 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 63919a8..2ad592a 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -8385,6 +8385,12 @@
   Value *Callee = CS.getCalledValue();
   const PointerType *PTy = cast<PointerType>(Callee->getType());
   const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+  const ParamAttrsList *Attrs = CS.getParamAttrs();
+
+  // If the call already has the 'nest' attribute somewhere then give up -
+  // otherwise 'nest' would occur twice after splicing in the chain.
+  if (Attrs && Attrs->hasAttrSomewhere(ParamAttr::Nest))
+    return 0;
 
   IntrinsicInst *Tramp =
     cast<IntrinsicInst>(cast<BitCastInst>(Callee)->getOperand(0));
@@ -8414,25 +8420,39 @@
       std::vector<Value*> NewArgs;
       NewArgs.reserve(unsigned(CS.arg_end()-CS.arg_begin())+1);
 
+      ParamAttrsVector NewAttrs;
+      NewAttrs.reserve(Attrs ? Attrs->size() + 1 : 1);
+
       // Insert the nest argument into the call argument list, which may
-      // mean appending it.
+      // mean appending it.  Likewise for attributes.
+
+      // Add any function result attributes.
+      uint16_t Attr = Attrs ? Attrs->getParamAttrs(0) : 0;
+      if (Attr)
+        NewAttrs.push_back (ParamAttrsWithIndex::get(0, Attr));
+
       {
         unsigned Idx = 1;
         CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
         do {
           if (Idx == NestIdx) {
-            // Add the chain argument.
+            // Add the chain argument and attributes.
             Value *NestVal = Tramp->getOperand(3);
             if (NestVal->getType() != NestTy)
               NestVal = new BitCastInst(NestVal, NestTy, "nest", Caller);
             NewArgs.push_back(NestVal);
+            NewAttrs.push_back(ParamAttrsWithIndex::get(NestIdx, NestAttr));
           }
 
           if (I == E)
             break;
 
-          // Add the original argument.
+          // Add the original argument and attributes.
           NewArgs.push_back(*I);
+          Attr = Attrs ? Attrs->getParamAttrs(Idx) : 0;
+          if (Attr)
+            NewAttrs.push_back
+              (ParamAttrsWithIndex::get(Idx + (Idx >= NestIdx), Attr));
 
           ++Idx, ++I;
         } while (1);
@@ -8440,41 +8460,28 @@
 
       // The trampoline may have been bitcast to a bogus type (FTy).
       // Handle this by synthesizing a new function type, equal to FTy
-      // with the chain parameter inserted.  Likewise for attributes.
+      // with the chain parameter inserted.
 
-      const ParamAttrsList *Attrs = CS.getParamAttrs();
       std::vector<const Type*> NewTypes;
-      ParamAttrsVector NewAttrs;
       NewTypes.reserve(FTy->getNumParams()+1);
 
-      // Add any function result attributes.
-      uint16_t Attr = Attrs ? Attrs->getParamAttrs(0) : 0;
-      if (Attr)
-        NewAttrs.push_back (ParamAttrsWithIndex::get(0, Attr));
-
       // Insert the chain's type into the list of parameter types, which may
-      // mean appending it.  Likewise for the chain's attributes.
+      // mean appending it.
       {
         unsigned Idx = 1;
         FunctionType::param_iterator I = FTy->param_begin(),
           E = FTy->param_end();
 
         do {
-          if (Idx == NestIdx) {
-            // Add the chain's type and attributes.
+          if (Idx == NestIdx)
+            // Add the chain's type.
             NewTypes.push_back(NestTy);
-            NewAttrs.push_back(ParamAttrsWithIndex::get(NestIdx, NestAttr));
-          }
 
           if (I == E)
             break;
 
-          // Add the original type and attributes.
+          // Add the original type.
           NewTypes.push_back(*I);
-          Attr = Attrs ? Attrs->getParamAttrs(Idx) : 0;
-          if (Attr)
-            NewAttrs.push_back
-              (ParamAttrsWithIndex::get(Idx + (Idx >= NestIdx), Attr));
 
           ++Idx, ++I;
         } while (1);