Skip to content

Commit

Permalink
Change CloneFunctionInto to always clone Argument attributes induvidu…
Browse files Browse the repository at this point in the history
…ally,

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
  • Loading branch information
jgouly committed Apr 10, 2013
1 parent 4d0e8a8 commit 0f57a98
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 23 deletions.
41 changes: 19 additions & 22 deletions lib/Transforms/Utils/CloneFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
29 changes: 28 additions & 1 deletion unittests/Transforms/Utils/Cloning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
}

}

0 comments on commit 0f57a98

Please sign in to comment.