diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h index a9e040b825c..5f0aa3374ee 100644 --- a/include/llvm/IR/IRBuilder.h +++ b/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 Args, + ArrayRef 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 Args = None, + ArrayRef OpBundles = None, const Twine &Name = "") { + return Insert(CallInst::Create(Callee, Args, OpBundles), Name); + } + CallInst *CreateCall(Value *Callee, ArrayRef Args, + const Twine &Name) { return Insert(CallInst::Create(Callee, Args), Name); } diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index cde26cc24c2..c3fbaf2adfc 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2267,16 +2267,23 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { const AttributeSet &NewCallerPAL = AttributeSet::get(Callee->getContext(), attrVec); + SmallVector 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(Caller)) { - NC = Builder->CreateInvoke(Callee, II->getNormalDest(), - II->getUnwindDest(), Args); + NC = Builder->CreateInvoke(Callee, II->getNormalDest(), II->getUnwindDest(), + Args, OpBundles); NC->takeName(II); cast(NC)->setCallingConv(II->getCallingConv()); cast(NC)->setAttributes(NewCallerPAL); } else { CallInst *CI = cast(Caller); - NC = Builder->CreateCall(Callee, Args); + NC = Builder->CreateCall(Callee, Args, OpBundles); NC->takeName(CI); if (CI->isTailCall()) cast(NC)->setTailCall(); diff --git a/test/Transforms/InstCombine/cast-callee-deopt-bundles.ll b/test/Transforms/InstCombine/cast-callee-deopt-bundles.ll new file mode 100644 index 00000000000..0f8601b855c --- /dev/null +++ b/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 +}