diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2016-04-29 07:22:36 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2016-04-29 07:22:36 +0000 |
| commit | 1a5799fe3e28d3c2c8a683cc6e49ccf7ba1d4893 (patch) | |
| tree | b491bc7b2050c701b7390406f075b8b1cec46e28 | |
| parent | c60d8f8fd046bfff96c6b1c834a904bdf74274a7 (diff) | |
| download | bcm5719-llvm-1a5799fe3e28d3c2c8a683cc6e49ccf7ba1d4893.tar.gz bcm5719-llvm-1a5799fe3e28d3c2c8a683cc6e49ccf7ba1d4893.zip | |
[DeadArgumentElimination] Propagate operand bundles to promoted call sites
We neglected to transfer operand bundles when performing argument
promotion.
llvm-svn: 268008
| -rw-r--r-- | llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp | 14 | ||||
| -rw-r--r-- | llvm/test/Transforms/DeadArgElim/funclet.ll | 29 |
2 files changed, 39 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp index 3ca5acda34c..627e05b4167 100644 --- a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -255,14 +255,17 @@ bool DAE::DeleteDeadVarargs(Function &Fn) { PAL = AttributeSet::get(Fn.getContext(), AttributesVec); } + SmallVector<OperandBundleDef, 1> OpBundles; + CS.getOperandBundlesAsDefs(OpBundles); + Instruction *New; if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) { New = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(), - Args, "", Call); + Args, OpBundles, "", Call); cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv()); cast<InvokeInst>(New)->setAttributes(PAL); } else { - New = CallInst::Create(NF, Args, "", Call); + New = CallInst::Create(NF, Args, OpBundles, "", Call); cast<CallInst>(New)->setCallingConv(CS.getCallingConv()); cast<CallInst>(New)->setAttributes(PAL); if (cast<CallInst>(Call)->isTailCall()) @@ -948,14 +951,17 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) { // Reconstruct the AttributesList based on the vector we constructed. AttributeSet NewCallPAL = AttributeSet::get(F->getContext(), AttributesVec); + SmallVector<OperandBundleDef, 1> OpBundles; + CS.getOperandBundlesAsDefs(OpBundles); + Instruction *New; if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) { New = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(), - Args, "", Call->getParent()); + Args, OpBundles, "", Call->getParent()); cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv()); cast<InvokeInst>(New)->setAttributes(NewCallPAL); } else { - New = CallInst::Create(NF, Args, "", Call); + New = CallInst::Create(NF, Args, OpBundles, "", Call); cast<CallInst>(New)->setCallingConv(CS.getCallingConv()); cast<CallInst>(New)->setAttributes(NewCallPAL); if (cast<CallInst>(Call)->isTailCall()) diff --git a/llvm/test/Transforms/DeadArgElim/funclet.ll b/llvm/test/Transforms/DeadArgElim/funclet.ll new file mode 100644 index 00000000000..36b0d3aa626 --- /dev/null +++ b/llvm/test/Transforms/DeadArgElim/funclet.ll @@ -0,0 +1,29 @@ +; RUN: opt -S -deadargelim < %s | FileCheck %s +target triple = "x86_64-pc-windows-msvc" + +define internal void @callee(i8*) { +entry: + call void @thunk() + ret void +} + +define void @test1() personality i32 (...)* @__CxxFrameHandler3 { +entry: + invoke void @thunk() + to label %good1 unwind label %bad1 + +good1: ; preds = %entry-block + ret void + +bad1: ; preds = %entry-block + %pad1 = cleanuppad within none [] + call void @callee(i8* null) [ "funclet"(token %pad1) ] + cleanupret from %pad1 unwind to caller +} +; CHECK-LABEL: define void @test1( +; CHECK: %[[pad:.*]] = cleanuppad within none [] +; CHECK-NEXT: call void @callee() [ "funclet"(token %[[pad]]) ] + +declare void @thunk() + +declare i32 @__CxxFrameHandler3(...) |

