diff options
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/IPO/ArgumentPromotion.cpp | 35 | ||||
-rw-r--r-- | lib/Transforms/IPO/DeadArgumentElimination.cpp | 38 | ||||
-rw-r--r-- | lib/Transforms/IPO/ExtractFunction.cpp | 1 | ||||
-rw-r--r-- | lib/Transforms/IPO/LowerSetJmp.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/IPO/PruneEH.cpp | 1 | ||||
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 29 | ||||
-rw-r--r-- | lib/Transforms/Scalar/LowerGC.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SimplifyCFG.cpp | 18 | ||||
-rw-r--r-- | lib/Transforms/Utils/CloneFunction.cpp | 5 | ||||
-rw-r--r-- | lib/Transforms/Utils/CloneModule.cpp | 3 | ||||
-rw-r--r-- | lib/Transforms/Utils/InlineFunction.cpp | 1 | ||||
-rw-r--r-- | lib/Transforms/Utils/LowerInvoke.cpp | 4 | ||||
-rw-r--r-- | lib/Transforms/Utils/SimplifyCFG.cpp | 2 |
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; |