[llvm] r204866 - CloneFunction: Clone all attributes, including the CC

Reid Kleckner reid at kleckner.net
Wed Mar 26 15:26:35 PDT 2014


Author: rnk
Date: Wed Mar 26 17:26:35 2014
New Revision: 204866

URL: http://llvm.org/viewvc/llvm-project?rev=204866&view=rev
Log:
CloneFunction: Clone all attributes, including the CC

Summary:
Tested with a unit test because we don't appear to have any transforms
that use this other than ASan, I think.

Fixes PR17935.

Reviewers: nicholas

CC: llvm-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D3194

Modified:
    llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
    llvm/trunk/unittests/Transforms/Utils/Cloning.cpp

Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=204866&r1=204865&r2=204866&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Wed Mar 26 17:26:35 2014
@@ -89,26 +89,28 @@ void llvm::CloneFunctionInto(Function *N
     assert(VMap.count(I) && "No mapping from source argument specified!");
 #endif
 
+  // Copy all attributes other than those stored in the AttributeSet.  We need
+  // to remap the parameter indices of the AttributeSet.
+  AttributeSet NewAttrs = NewFunc->getAttributes();
+  NewFunc->copyAttributesFrom(OldFunc);
+  NewFunc->setAttributes(NewAttrs);
+
   AttributeSet OldAttrs = OldFunc->getAttributes();
   // Clone any argument attributes that are present in the VMap.
-  for (Function::const_arg_iterator I = OldFunc->arg_begin(),
-                                    E = OldFunc->arg_end();
-       I != E; ++I)
-    if (Argument *Anew = dyn_cast<Argument>(VMap[I])) {
+  for (const Argument &OldArg : OldFunc->args())
+    if (Argument *NewArg = dyn_cast<Argument>(VMap[&OldArg])) {
       AttributeSet attrs =
-          OldAttrs.getParamAttributes(I->getArgNo() + 1);
+          OldAttrs.getParamAttributes(OldArg.getArgNo() + 1);
       if (attrs.getNumSlots() > 0)
-        Anew->addAttr(attrs);
+        NewArg->addAttr(attrs);
     }
 
-  NewFunc->setAttributes(NewFunc->getAttributes()
-                         .addAttributes(NewFunc->getContext(),
-                                        AttributeSet::ReturnIndex,
-                                        OldAttrs.getRetAttributes()));
-  NewFunc->setAttributes(NewFunc->getAttributes()
-                         .addAttributes(NewFunc->getContext(),
-                                        AttributeSet::FunctionIndex,
-                                        OldAttrs.getFnAttributes()));
+  NewFunc->setAttributes(
+      NewFunc->getAttributes()
+          .addAttributes(NewFunc->getContext(), AttributeSet::ReturnIndex,
+                         OldAttrs.getRetAttributes())
+          .addAttributes(NewFunc->getContext(), AttributeSet::FunctionIndex,
+                         OldAttrs.getFnAttributes()));
 
   // Loop over all of the basic blocks in the function, cloning them as
   // appropriate.  Note that we save BE this way in order to handle cloning of

Modified: llvm/trunk/unittests/Transforms/Utils/Cloning.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/Cloning.cpp?rev=204866&r1=204865&r2=204866&view=diff
==============================================================================
--- llvm/trunk/unittests/Transforms/Utils/Cloning.cpp (original)
+++ llvm/trunk/unittests/Transforms/Utils/Cloning.cpp Wed Mar 26 17:26:35 2014
@@ -180,6 +180,29 @@ TEST_F(CloneInstruction, Attributes) {
   delete F2;
 }
 
+TEST_F(CloneInstruction, CallingConvention) {
+  Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
+  FunctionType *FT1 =  FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
+
+  Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
+  F1->setCallingConv(CallingConv::Cold);
+  BasicBlock *BB = BasicBlock::Create(context, "", F1);
+  IRBuilder<> Builder(BB);
+  Builder.CreateRetVoid();
+
+  Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
+
+  SmallVector<ReturnInst*, 4> Returns;
+  ValueToValueMapTy VMap;
+  VMap[F1->arg_begin()] = F2->arg_begin();
+
+  CloneFunctionInto(F2, F1, VMap, false, Returns);
+  EXPECT_EQ(CallingConv::Cold, F2->getCallingConv());
+
+  delete F1;
+  delete F2;
+}
+
 class CloneFunc : public ::testing::Test {
 protected:
   virtual void SetUp() {





More information about the llvm-commits mailing list