[InstCombine] Don't drop operand bundles
authorSanjoy Das <sanjoy@playingwithpointers.com>
Wed, 25 Nov 2015 00:42:19 +0000 (00:42 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Wed, 25 Nov 2015 00:42:19 +0000 (00:42 +0000)
Reviewers: majnemer

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D14857

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254046 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/IRBuilder.h
lib/Transforms/InstCombine/InstCombineCalls.cpp
test/Transforms/InstCombine/cast-callee-deopt-bundles.ll [new file with mode: 0644]

index a9e040b825c013cd6d83df512098547a4135190f..5f0aa3374ee29053cea802fa47fe56e3f519ac6b 100644 (file)
@@ -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);
   }
 
index cde26cc24c29d922656d14814582fd87fc5f05a0..c3fbaf2adfc04bcd950e64841fdcdcf74325e800 100644 (file)
@@ -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/test/Transforms/InstCombine/cast-callee-deopt-bundles.ll b/test/Transforms/InstCombine/cast-callee-deopt-bundles.ll
new file mode 100644 (file)
index 0000000..0f8601b
--- /dev/null
@@ -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
+}