summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Gouly <joey.gouly@arm.com>2013-04-10 10:37:38 +0000
committerJoey Gouly <joey.gouly@arm.com>2013-04-10 10:37:38 +0000
commit0f57a98a65df5e617ed0adcf0ca0877745c84a79 (patch)
tree10743791225d1222121f38f58c7a3a37f659d9f5
parent4d0e8a8a3e2e5b98f598acad4d57452b99d52e74 (diff)
downloadllvm-0f57a98a65df5e617ed0adcf0ca0877745c84a79.tar.gz
llvm-0f57a98a65df5e617ed0adcf0ca0877745c84a79.tar.bz2
llvm-0f57a98a65df5e617ed0adcf0ca0877745c84a79.tar.xz
Change CloneFunctionInto to always clone Argument attributes induvidually,
rather than checking if the source and destination have the same number of arguments and copying the attributes over directly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179169 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Utils/CloneFunction.cpp41
-rw-r--r--unittests/Transforms/Utils/Cloning.cpp29
2 files changed, 47 insertions, 23 deletions
diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp
index 63d7a1d52a..be8d39e128 100644
--- a/lib/Transforms/Utils/CloneFunction.cpp
+++ b/lib/Transforms/Utils/CloneFunction.cpp
@@ -87,29 +87,26 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
assert(VMap.count(I) && "No mapping from source argument specified!");
#endif
- // Clone any attributes.
- if (NewFunc->arg_size() == OldFunc->arg_size())
- NewFunc->copyAttributesFrom(OldFunc);
- else {
- //Some arguments were deleted with the VMap. Copy arguments one by one
- for (Function::const_arg_iterator I = OldFunc->arg_begin(),
- E = OldFunc->arg_end(); I != E; ++I)
- if (Argument* Anew = dyn_cast<Argument>(VMap[I])) {
- AttributeSet attrs = OldFunc->getAttributes()
- .getParamAttributes(I->getArgNo() + 1);
- if (attrs.getNumSlots() > 0)
- Anew->addAttr(attrs);
- }
- NewFunc->setAttributes(NewFunc->getAttributes()
- .addAttributes(NewFunc->getContext(),
- AttributeSet::ReturnIndex,
- OldFunc->getAttributes()));
- NewFunc->setAttributes(NewFunc->getAttributes()
- .addAttributes(NewFunc->getContext(),
- AttributeSet::FunctionIndex,
- OldFunc->getAttributes()));
+ 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])) {
+ AttributeSet attrs =
+ OldAttrs.getParamAttributes(I->getArgNo() + 1);
+ if (attrs.getNumSlots() > 0)
+ Anew->addAttr(attrs);
+ }
- }
+ NewFunc->setAttributes(NewFunc->getAttributes()
+ .addAttributes(NewFunc->getContext(),
+ AttributeSet::ReturnIndex,
+ OldAttrs.getRetAttributes()));
+ NewFunc->setAttributes(NewFunc->getAttributes()
+ .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
diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp
index cd304e7200..5930d5ef98 100644
--- a/unittests/Transforms/Utils/Cloning.cpp
+++ b/unittests/Transforms/Utils/Cloning.cpp
@@ -7,12 +7,15 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/IR/Instructions.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Constant.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/Transforms/Utils/Cloning.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -143,4 +146,28 @@ TEST_F(CloneInstruction, Exact) {
EXPECT_TRUE(this->clone(SDiv)->isExact());
}
+TEST_F(CloneInstruction, Attributes) {
+ Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
+ FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
+
+ Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
+ BasicBlock *BB = BasicBlock::Create(context, "", F1);
+ IRBuilder<> Builder(BB);
+ Builder.CreateRetVoid();
+
+ Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
+
+ Attribute::AttrKind AK[] = { Attribute::NoCapture };
+ AttributeSet AS = AttributeSet::get(context, 0, AK);
+ Argument *A = F1->arg_begin();
+ A->addAttr(AS);
+
+ SmallVector<ReturnInst*, 4> Returns;
+ ValueToValueMapTy VMap;
+ VMap[A] = UndefValue::get(A->getType());
+
+ CloneFunctionInto(F2, F1, VMap, false, Returns);
+ EXPECT_FALSE(F2->arg_begin()->hasNoCaptureAttr());
+}
+
}