aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/IPO/ArgumentPromotion.cpp35
-rw-r--r--lib/Transforms/IPO/DeadArgumentElimination.cpp38
-rw-r--r--lib/Transforms/IPO/ExtractFunction.cpp1
-rw-r--r--lib/Transforms/IPO/LowerSetJmp.cpp2
-rw-r--r--lib/Transforms/IPO/PruneEH.cpp1
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp29
-rw-r--r--lib/Transforms/Scalar/LowerGC.cpp2
-rw-r--r--lib/Transforms/Scalar/SimplifyCFG.cpp18
-rw-r--r--lib/Transforms/Utils/CloneFunction.cpp5
-rw-r--r--lib/Transforms/Utils/CloneModule.cpp3
-rw-r--r--lib/Transforms/Utils/InlineFunction.cpp1
-rw-r--r--lib/Transforms/Utils/LowerInvoke.cpp4
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp2
13 files changed, 104 insertions, 37 deletions
diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp
index 7479c8ee67..26d8853891 100644
--- a/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -35,6 +35,7 @@
#include "llvm/Module.h"
#include "llvm/CallGraphSCCPass.h"
#include "llvm/Instructions.h"
+#include "llvm/ParameterAttributes.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Target/TargetData.h"
@@ -139,10 +140,10 @@ bool ArgPromotion::PromoteArguments(CallGraphNode *CGN) {
// No promotable pointer arguments.
if (PointerArgs.empty()) return false;
- // Okay, promote all of the arguments are rewrite the callees!
+ // Okay, promote all of the arguments and rewrite the callees!
Function *NewF = DoPromotion(F, PointerArgs);
- // Update the call graph to know that the old function is gone.
+ // Update the call graph to know that the function has been transformed.
getAnalysis<CallGraph>().changeFunction(F, NewF);
return true;
}
@@ -349,9 +350,23 @@ Function *ArgPromotion::DoPromotion(Function *F,
// what the new GEP/Load instructions we are inserting look like.
std::map<std::vector<Value*>, LoadInst*> OriginalLoads;
- for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
+ // ParamAttrs - Keep track of the parameter attributes for the arguments
+ // that we are *not* promoting. For the ones that we do promote, the parameter
+ // attributes are lost
+ ParamAttrsVector ParamAttrsVec;
+ const ParamAttrsList *PAL = F->getParamAttrs();
+
+ unsigned index = 1;
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E;
+ ++I, ++index)
if (!ArgsToPromote.count(I)) {
Params.push_back(I->getType());
+ if (PAL) {
+ unsigned attrs = PAL->getParamAttrs(index);
+ if (attrs)
+ ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Params.size(),
+ attrs));
+ }
} else if (I->use_empty()) {
++NumArgumentsDead;
} else {
@@ -387,6 +402,13 @@ Function *ArgPromotion::DoPromotion(Function *F,
const Type *RetTy = FTy->getReturnType();
+ // Recompute the parameter attributes list based on the new arguments for
+ // the function.
+ if (ParamAttrsVec.empty())
+ PAL = 0;
+ else
+ PAL = ParamAttrsList::get(ParamAttrsVec);
+
// Work around LLVM bug PR56: the CWriter cannot emit varargs functions which
// have zero fixed arguments.
bool ExtraArgHack = false;
@@ -394,11 +416,14 @@ Function *ArgPromotion::DoPromotion(Function *F,
ExtraArgHack = true;
Params.push_back(Type::Int32Ty);
}
+
+ // Construct the new function type using the new arguments.
FunctionType *NFTy = FunctionType::get(RetTy, Params, FTy->isVarArg());
- // Create the new function body and insert it into the module...
+ // Create the new function body and insert it into the module...
Function *NF = new Function(NFTy, F->getLinkage(), F->getName());
NF->setCallingConv(F->getCallingConv());
+ NF->setParamAttrs(PAL);
F->getParent()->getFunctionList().insert(F, NF);
// Get the alias analysis information that we need to update to reflect our
@@ -449,9 +474,11 @@ Function *ArgPromotion::DoPromotion(Function *F,
New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
Args.begin(), Args.end(), "", Call);
cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
+ cast<InvokeInst>(New)->setParamAttrs(PAL);
} else {
New = new CallInst(NF, Args.begin(), Args.end(), "", Call);
cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
+ cast<CallInst>(New)->setParamAttrs(PAL);
if (cast<CallInst>(Call)->isTailCall())
cast<CallInst>(New)->setTailCall();
}
diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp
index 3d345eefaa..a76a43a20b 100644
--- a/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -26,6 +26,7 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
+#include "llvm/ParameterAttributes.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
@@ -157,6 +158,7 @@ bool DAE::DeleteDeadVarargs(Function &Fn) {
// Create the new function body and insert it into the module...
Function *NF = new Function(NFTy, Fn.getLinkage());
NF->setCallingConv(Fn.getCallingConv());
+ NF->setParamAttrs(Fn.getParamAttrs());
Fn.getParent()->getFunctionList().insert(&Fn, NF);
NF->takeName(&Fn);
@@ -176,9 +178,11 @@ bool DAE::DeleteDeadVarargs(Function &Fn) {
New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
Args.begin(), Args.end(), "", Call);
cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
+ cast<InvokeInst>(New)->setParamAttrs(NF->getParamAttrs());
} else {
New = new CallInst(NF, Args.begin(), Args.end(), "", Call);
cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
+ cast<CallInst>(New)->setParamAttrs(NF->getParamAttrs());
if (cast<CallInst>(Call)->isTailCall())
cast<CallInst>(New)->setTailCall();
}
@@ -233,10 +237,10 @@ static inline bool CallPassesValueThoughVararg(Instruction *Call,
// (used in a computation), MaybeLive (only passed as an argument to a call), or
// Dead (not used).
DAE::Liveness DAE::getArgumentLiveness(const Argument &A) {
- const FunctionType *FTy = A.getParent()->getFunctionType();
+ const Function *F = A.getParent();
// If this is the return value of a struct function, it's not really dead.
- if (FTy->isStructReturn() && &*A.getParent()->arg_begin() == &A)
+ if (F->isStructReturn() && &*(F->arg_begin()) == &A)
return Live;
if (A.use_empty()) // First check, directly dead?
@@ -488,10 +492,32 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) {
const FunctionType *FTy = F->getFunctionType();
std::vector<const Type*> Params;
- for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
- if (!DeadArguments.count(I))
+ // Set up to build a new list of parameter attributes
+ ParamAttrsVector ParamAttrsVec;
+ const ParamAttrsList *PAL = F->getParamAttrs();
+
+ // Construct the new parameter list from non-dead arguments. Also construct
+ // a new set of parameter attributes to correspond.
+ unsigned index = 1;
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E;
+ ++I, ++index)
+ if (!DeadArguments.count(I)) {
Params.push_back(I->getType());
+ if (PAL) {
+ uint16_t Attrs = PAL->getParamAttrs(index);
+ if (Attrs != ParamAttr::None)
+ ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Params.size(),
+ Attrs));
+ }
+ }
+
+ // Reconstruct the ParamAttrsList based on the vector we constructed.
+ if (ParamAttrsVec.empty())
+ PAL = 0;
+ else
+ PAL = ParamAttrsList::get(ParamAttrsVec);
+ // Make the function return void if the return value is dead.
const Type *RetTy = FTy->getReturnType();
if (DeadRetVal.count(F)) {
RetTy = Type::VoidTy;
@@ -507,11 +533,13 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) {
Params.push_back(Type::Int32Ty);
}
+ // Create the new function type based on the recomputed parameters.
FunctionType *NFTy = FunctionType::get(RetTy, Params, FTy->isVarArg());
// Create the new function body and insert it into the module...
Function *NF = new Function(NFTy, F->getLinkage());
NF->setCallingConv(F->getCallingConv());
+ NF->setParamAttrs(PAL);
F->getParent()->getFunctionList().insert(F, NF);
NF->takeName(F);
@@ -542,9 +570,11 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) {
New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
Args.begin(), Args.end(), "", Call);
cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
+ cast<InvokeInst>(New)->setParamAttrs(PAL);
} else {
New = new CallInst(NF, Args.begin(), Args.end(), "", Call);
cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
+ cast<CallInst>(New)->setParamAttrs(PAL);
if (cast<CallInst>(Call)->isTailCall())
cast<CallInst>(New)->setTailCall();
}
diff --git a/lib/Transforms/IPO/ExtractFunction.cpp b/lib/Transforms/IPO/ExtractFunction.cpp
index ed22465f89..e5b2d41d52 100644
--- a/lib/Transforms/IPO/ExtractFunction.cpp
+++ b/lib/Transforms/IPO/ExtractFunction.cpp
@@ -95,6 +95,7 @@ namespace {
Function *New = new Function(I->getFunctionType(),
GlobalValue::ExternalLinkage);
New->setCallingConv(I->getCallingConv());
+ New->setParamAttrs(I->getParamAttrs());
// If it's not the named function, delete the body of the function
I->dropAllReferences();
diff --git a/lib/Transforms/IPO/LowerSetJmp.cpp b/lib/Transforms/IPO/LowerSetJmp.cpp
index dbc3199162..90ece1799d 100644
--- a/lib/Transforms/IPO/LowerSetJmp.cpp
+++ b/lib/Transforms/IPO/LowerSetJmp.cpp
@@ -476,6 +476,8 @@ void LowerSetJmp::visitCallInst(CallInst& CI)
InvokeInst* II = new
InvokeInst(CI.getCalledValue(), NewBB, PrelimBBMap[Func],
Params.begin(), Params.end(), CI.getName(), Term);
+ II->setCallingConv(CI.getCallingConv());
+ II->setParamAttrs(CI.getParamAttrs());
// Replace the old call inst with the invoke inst and remove the call.
CI.replaceAllUsesWith(II);
diff --git a/lib/Transforms/IPO/PruneEH.cpp b/lib/Transforms/IPO/PruneEH.cpp
index 52f8d5efbf..631b5f797a 100644
--- a/lib/Transforms/IPO/PruneEH.cpp
+++ b/lib/Transforms/IPO/PruneEH.cpp
@@ -156,6 +156,7 @@ bool PruneEH::SimplifyFunction(Function *F) {
Args.begin(), Args.end(), "", II);
Call->takeName(II);
Call->setCallingConv(II->getCallingConv());
+ Call->setParamAttrs(II->getParamAttrs());
// Anything that used the value produced by the invoke instruction
// now uses the value produced by the call instruction.
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index e90d1909ae..52c66a5d87 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -7994,13 +7994,15 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
const FunctionType *FT = Callee->getFunctionType();
const Type *OldRetTy = Caller->getType();
- const FunctionType *ActualFT =
- cast<FunctionType>(cast<PointerType>(CE->getType())->getElementType());
-
+ const ParamAttrsList* CallerPAL = 0;
+ if (CallInst *CallerCI = dyn_cast<CallInst>(Caller))
+ CallerPAL = CallerCI->getParamAttrs();
+ else if (InvokeInst *CallerII = dyn_cast<InvokeInst>(Caller))
+ CallerPAL = CallerII->getParamAttrs();
+
// If the parameter attributes are not compatible, don't do the xform. We
// don't want to lose an sret attribute or something.
- if (!ParamAttrsList::areCompatible(FT->getParamAttrs(),
- ActualFT->getParamAttrs()))
+ if (!ParamAttrsList::areCompatible(CallerPAL, Callee->getParamAttrs()))
return false;
// Check to see if we are changing the return type...
@@ -8135,12 +8137,15 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
NC = new InvokeInst(Callee, II->getNormalDest(), II->getUnwindDest(),
Args.begin(), Args.end(), Caller->getName(), Caller);
cast<InvokeInst>(NC)->setCallingConv(II->getCallingConv());
+ cast<InvokeInst>(NC)->setParamAttrs(CallerPAL);
} else {
NC = new CallInst(Callee, Args.begin(), Args.end(),
Caller->getName(), Caller);
- if (cast<CallInst>(Caller)->isTailCall())
+ CallInst *CI = cast<CallInst>(Caller);
+ if (CI->isTailCall())
cast<CallInst>(NC)->setTailCall();
- cast<CallInst>(NC)->setCallingConv(cast<CallInst>(Caller)->getCallingConv());
+ cast<CallInst>(NC)->setCallingConv(CI->getCallingConv());
+ cast<CallInst>(NC)->setParamAttrs(CallerPAL);
}
// Insert a cast of the return type as necessary.
@@ -8191,7 +8196,7 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
const PointerType *NestFPTy = cast<PointerType>(NestF->getType());
const FunctionType *NestFTy = cast<FunctionType>(NestFPTy->getElementType());
- if (const ParamAttrsList *NestAttrs = NestFTy->getParamAttrs()) {
+ if (const ParamAttrsList *NestAttrs = NestF->getParamAttrs()) {
unsigned NestIdx = 1;
const Type *NestTy = 0;
uint16_t NestAttr = 0;
@@ -8239,7 +8244,7 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
// Handle this by synthesizing a new function type, equal to FTy
// with the chain parameter inserted. Likewise for attributes.
- const ParamAttrsList *Attrs = FTy->getParamAttrs();
+ const ParamAttrsList *Attrs = CS.getParamAttrs();
std::vector<const Type*> NewTypes;
ParamAttrsVector NewAttrs;
NewTypes.reserve(FTy->getNumParams()+1);
@@ -8280,10 +8285,10 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
// Replace the trampoline call with a direct call. Let the generic
// code sort out any function type mismatches.
FunctionType *NewFTy =
- FunctionType::get(FTy->getReturnType(), NewTypes, FTy->isVarArg(),
- ParamAttrsList::get(NewAttrs));
+ FunctionType::get(FTy->getReturnType(), NewTypes, FTy->isVarArg());
Constant *NewCallee = NestF->getType() == PointerType::get(NewFTy) ?
NestF : ConstantExpr::getBitCast(NestF, PointerType::get(NewFTy));
+ const ParamAttrsList *NewPAL = ParamAttrsList::get(NewAttrs);
Instruction *NewCaller;
if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {
@@ -8292,6 +8297,7 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
NewArgs.begin(), NewArgs.end(),
Caller->getName(), Caller);
cast<InvokeInst>(NewCaller)->setCallingConv(II->getCallingConv());
+ cast<InvokeInst>(NewCaller)->setParamAttrs(NewPAL);
} else {
NewCaller = new CallInst(NewCallee, NewArgs.begin(), NewArgs.end(),
Caller->getName(), Caller);
@@ -8299,6 +8305,7 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
cast<CallInst>(NewCaller)->setTailCall();
cast<CallInst>(NewCaller)->
setCallingConv(cast<CallInst>(Caller)->getCallingConv());
+ cast<CallInst>(NewCaller)->setParamAttrs(NewPAL);
}
if (Caller->getType() != Type::VoidTy && !Caller->use_empty())
Caller->replaceAllUsesWith(NewCaller);
diff --git a/lib/Transforms/Scalar/LowerGC.cpp b/lib/Transforms/Scalar/LowerGC.cpp
index bac7ac799b..aff3f2cb30 100644
--- a/lib/Transforms/Scalar/LowerGC.cpp
+++ b/lib/Transforms/Scalar/LowerGC.cpp
@@ -339,6 +339,8 @@ bool LowerGC::runOnFunction(Function &F) {
Value *II = new InvokeInst(CI->getCalledValue(), NewBB, Cleanup,
Args.begin(), Args.end(), CI->getName(), CBB);
+ cast<InvokeInst>(II)->setCallingConv(CI->getCallingConv());
+ cast<InvokeInst>(II)->setParamAttrs(CI->getParamAttrs());
CI->replaceAllUsesWith(II);
delete CI;
}
diff --git a/lib/Transforms/Scalar/SimplifyCFG.cpp b/lib/Transforms/Scalar/SimplifyCFG.cpp
index 3717a161ae..22d81c881e 100644
--- a/lib/Transforms/Scalar/SimplifyCFG.cpp
+++ b/lib/Transforms/Scalar/SimplifyCFG.cpp
@@ -96,16 +96,11 @@ static bool IsNoReturn(const CallInst *CI) {
if (Attrs->paramHasAttr(0, ParamAttr::NoReturn))
return true;
- if (const Function *Callee = CI->getCalledFunction()) {
+ if (const Function *Callee = CI->getCalledFunction())
if (const ParamAttrsList *Attrs = Callee->getParamAttrs())
if (Attrs->paramHasAttr(0, ParamAttr::NoReturn))
return true;
-
- const FunctionType *FT = Callee->getFunctionType();
- if (const ParamAttrsList *Attrs = FT->getParamAttrs())
- if (Attrs->paramHasAttr(0, ParamAttr::NoReturn))
- return true;
- }
+
return false;
}
@@ -115,16 +110,11 @@ static bool IsNoUnwind(const InvokeInst *II) {
if (Attrs->paramHasAttr(0, ParamAttr::NoUnwind))
return true;
- if (const Function *Callee = II->getCalledFunction()) {
+ if (const Function *Callee = II->getCalledFunction())
if (const ParamAttrsList *Attrs = Callee->getParamAttrs())
if (Attrs->paramHasAttr(0, ParamAttr::NoUnwind))
return true;
-
- const FunctionType *FT = Callee->getFunctionType();
- if (const ParamAttrsList *Attrs = FT->getParamAttrs())
- if (Attrs->paramHasAttr(0, ParamAttr::NoUnwind))
- return true;
- }
+
return false;
}
diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp
index d1faf01a94..f05085fca1 100644
--- a/lib/Transforms/Utils/CloneFunction.cpp
+++ b/lib/Transforms/Utils/CloneFunction.cpp
@@ -79,6 +79,9 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
assert(ValueMap.count(I) && "No mapping from source argument specified!");
#endif
+ // Clone the parameter attributes
+ NewFunc->setParamAttrs(OldFunc->getParamAttrs());
+
// 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
// recursive functions into themselves.
@@ -304,7 +307,7 @@ ConstantFoldMappedInstruction(const Instruction *I) {
/// effect of this is to copy significantly less code in cases where (for
/// example) a function call with constant arguments is inlined, and those
/// constant arguments cause a significant amount of code in the callee to be
-/// dead. Since this doesn't produce an exactly copy of the input, it can't be
+/// dead. Since this doesn't produce an exact copy of the input, it can't be
/// used for things like CloneFunction or CloneModule.
void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
DenseMap<const Value*, Value*> &ValueMap,
diff --git a/lib/Transforms/Utils/CloneModule.cpp b/lib/Transforms/Utils/CloneModule.cpp
index cd9f4b6cac..201da5be9a 100644
--- a/lib/Transforms/Utils/CloneModule.cpp
+++ b/lib/Transforms/Utils/CloneModule.cpp
@@ -66,6 +66,7 @@ Module *llvm::CloneModule(const Module *M,
new Function(cast<FunctionType>(I->getType()->getElementType()),
GlobalValue::ExternalLinkage, I->getName(), New);
NF->setCallingConv(I->getCallingConv());
+ NF->setParamAttrs(I->getParamAttrs());
ValueMap[I]= NF;
}
@@ -120,5 +121,3 @@ Module *llvm::CloneModule(const Module *M,
return New;
}
-
-// vim: sw=2
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp
index 96ad420d34..2a6d9ae9a2 100644
--- a/lib/Transforms/Utils/InlineFunction.cpp
+++ b/lib/Transforms/Utils/InlineFunction.cpp
@@ -88,6 +88,7 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
InvokeArgs.begin(), InvokeArgs.end(),
CI->getName(), BB->getTerminator());
II->setCallingConv(CI->getCallingConv());
+ II->setParamAttrs(CI->getParamAttrs());
// Make sure that anything using the call now uses the invoke!
CI->replaceAllUsesWith(II);
diff --git a/lib/Transforms/Utils/LowerInvoke.cpp b/lib/Transforms/Utils/LowerInvoke.cpp
index acb2b529c2..24b167ac87 100644
--- a/lib/Transforms/Utils/LowerInvoke.cpp
+++ b/lib/Transforms/Utils/LowerInvoke.cpp
@@ -212,9 +212,10 @@ bool LowerInvoke::insertCheapEHSupport(Function &F) {
std::vector<Value*> CallArgs(II->op_begin()+3, II->op_end());
// Insert a normal call instruction...
CallInst *NewCall = new CallInst(II->getCalledValue(),
- CallArgs.begin(), CallArgs.end(), "", II);
+ CallArgs.begin(), CallArgs.end(), "",II);
NewCall->takeName(II);
NewCall->setCallingConv(II->getCallingConv());
+ NewCall->setParamAttrs(II->getParamAttrs());
II->replaceAllUsesWith(NewCall);
// Insert an unconditional branch to the normal destination.
@@ -273,6 +274,7 @@ void LowerInvoke::rewriteExpensiveInvoke(InvokeInst *II, unsigned InvokeNo,
II);
NewCall->takeName(II);
NewCall->setCallingConv(II->getCallingConv());
+ NewCall->setParamAttrs(II->getParamAttrs());
II->replaceAllUsesWith(NewCall);
// Replace the invoke with an uncond branch.
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index 470daf36fe..1305fd92c7 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1376,6 +1376,7 @@ bool llvm::SimplifyCFG(BasicBlock *BB) {
CallInst *CI = new CallInst(II->getCalledValue(),
Args.begin(), Args.end(), II->getName(), BI);
CI->setCallingConv(II->getCallingConv());
+ CI->setParamAttrs(II->getParamAttrs());
// If the invoke produced a value, the Call now does instead
II->replaceAllUsesWith(CI);
delete II;
@@ -1751,6 +1752,7 @@ bool llvm::SimplifyCFG(BasicBlock *BB) {
Args.begin(), Args.end(),
II->getName(), BI);
CI->setCallingConv(II->getCallingConv());
+ CI->setParamAttrs(II->getParamAttrs());
// If the invoke produced a value, the Call does now instead.
II->replaceAllUsesWith(CI);
delete II;