From 0f57a98a65df5e617ed0adcf0ca0877745c84a79 Mon Sep 17 00:00:00 2001 From: Joey Gouly Date: Wed, 10 Apr 2013 10:37:38 +0000 Subject: [PATCH] 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 --- lib/Transforms/Utils/CloneFunction.cpp | 41 ++++++++++++-------------- unittests/Transforms/Utils/Cloning.cpp | 29 +++++++++++++++++- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp index 63d7a1d52aa..be8d39e128a 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(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(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 cd304e72008..5930d5ef98d 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 Returns; + ValueToValueMapTy VMap; + VMap[A] = UndefValue::get(A->getType()); + + CloneFunctionInto(F2, F1, VMap, false, Returns); + EXPECT_FALSE(F2->arg_begin()->hasNoCaptureAttr()); +} + } -- 2.34.1