aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2007-11-27 13:23:08 +0000
committerDuncan Sands <baldrick@free.fr>2007-11-27 13:23:08 +0000
commitdc024674ff96820d6020757b48d47f46d4c07db2 (patch)
tree843dfcaeb8f6c99de930a32020148b563005c2fd /lib/Transforms
parentf19341dec7361451f100a882a023b14583454d7e (diff)
downloadexternal_llvm-dc024674ff96820d6020757b48d47f46d4c07db2.zip
external_llvm-dc024674ff96820d6020757b48d47f46d4c07db2.tar.gz
external_llvm-dc024674ff96820d6020757b48d47f46d4c07db2.tar.bz2
Fix PR1146: parameter attributes are longer part of
the function type, instead they belong to functions and function calls. This is an updated and slightly corrected version of Reid Spencer's original patch. The only known problem is that auto-upgrading of bitcode files doesn't seem to work properly (see test/Bitcode/AutoUpgradeIntrinsics.ll). Hopefully a bitcode guru (who might that be? :) ) will fix it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44359 91177308-0d34-0410-b5e6-96231b3b80d8
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 7479c8e..26d8853 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 3d345ee..a76a43a 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 ed22465..e5b2d41 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 dbc3199..90ece17 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 52f8d5e..631b5f7 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 e90d190..52c66a5 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 bac7ac7..aff3f2c 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 3717a16..22d81c8 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 d1faf01..f05085f 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 cd9f4b6..201da5b 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 96ad420..2a6d9ae 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 acb2b52..24b167a 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 470daf3..1305fd9 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;