diff options
| -rw-r--r-- | llvm/include/llvm/IR/IRBuilder.h | 12 | ||||
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 13 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/cast-callee-deopt-bundles.ll | 11 |
3 files changed, 33 insertions, 3 deletions
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index a9e040b825c..5f0aa3374ee 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -691,6 +691,13 @@ public: return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args), Name); } + InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, + BasicBlock *UnwindDest, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> OpBundles, + const Twine &Name = "") { + return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args, + OpBundles), Name); + } ResumeInst *CreateResume(Value *Exn) { return Insert(ResumeInst::Create(Exn)); @@ -1528,7 +1535,12 @@ public: } CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args = None, + ArrayRef<OperandBundleDef> OpBundles = None, const Twine &Name = "") { + return Insert(CallInst::Create(Callee, Args, OpBundles), Name); + } + CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args, + const Twine &Name) { return Insert(CallInst::Create(Callee, Args), Name); } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index cde26cc24c2..c3fbaf2adfc 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2267,16 +2267,23 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { const AttributeSet &NewCallerPAL = AttributeSet::get(Callee->getContext(), attrVec); + SmallVector<OperandBundleDef, 1> OpBundles; + + // Convert the operand bundle uses to operand bundle defs. See InstrTypes.h + // for details on how these differ. + for (unsigned i = 0, e = CS.getNumOperandBundles(); i != e; ++i) + OpBundles.emplace_back(CS.getOperandBundleAt(i)); + Instruction *NC; if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) { - NC = Builder->CreateInvoke(Callee, II->getNormalDest(), - II->getUnwindDest(), Args); + NC = Builder->CreateInvoke(Callee, II->getNormalDest(), II->getUnwindDest(), + Args, OpBundles); NC->takeName(II); cast<InvokeInst>(NC)->setCallingConv(II->getCallingConv()); cast<InvokeInst>(NC)->setAttributes(NewCallerPAL); } else { CallInst *CI = cast<CallInst>(Caller); - NC = Builder->CreateCall(Callee, Args); + NC = Builder->CreateCall(Callee, Args, OpBundles); NC->takeName(CI); if (CI->isTailCall()) cast<CallInst>(NC)->setTailCall(); diff --git a/llvm/test/Transforms/InstCombine/cast-callee-deopt-bundles.ll b/llvm/test/Transforms/InstCombine/cast-callee-deopt-bundles.ll new file mode 100644 index 00000000000..0f8601b855c --- /dev/null +++ b/llvm/test/Transforms/InstCombine/cast-callee-deopt-bundles.ll @@ -0,0 +1,11 @@ +; RUN: opt -instcombine -S < %s | FileCheck %s + +declare void @foo(i32) + +define void @g() { +; CHECK-LABEL: @g( + entry: +; CHECK: call void @foo(i32 0) [ "deopt"() ] + call void bitcast (void (i32)* @foo to void ()*) () [ "deopt"() ] + ret void +} |

