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

llvm-svn: 204866
This commit is contained in:
Reid Kleckner 2014-03-26 22:26:35 +00:00
parent b9aea9383a
commit 23798a9731
2 changed files with 39 additions and 14 deletions

View File

@ -89,26 +89,28 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
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

View File

@ -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() {