Index: llvm/trunk/include/llvm/IR/CallSite.h =================================================================== --- llvm/trunk/include/llvm/IR/CallSite.h +++ llvm/trunk/include/llvm/IR/CallSite.h @@ -512,6 +512,10 @@ CALLSITE_DELEGATE_GETTER(countOperandBundlesOfType(ID)); } + bool isBundleOperand(unsigned Idx) const { + CALLSITE_DELEGATE_GETTER(isBundleOperand(Idx)); + } + IterTy arg_begin() const { CALLSITE_DELEGATE_GETTER(arg_begin()); } Index: llvm/trunk/include/llvm/IR/InstrTypes.h =================================================================== --- llvm/trunk/include/llvm/IR/InstrTypes.h +++ llvm/trunk/include/llvm/IR/InstrTypes.h @@ -1337,6 +1337,12 @@ return bundle_op_info_end()[-1].End; } + /// Return true if the operand at index \p Idx is a bundle operand. + bool isBundleOperand(unsigned Idx) const { + return hasOperandBundles() && Idx >= getBundleOperandsStartIndex() && + Idx < getBundleOperandsEndIndex(); + } + /// \brief Return the total number operands (not operand bundles) used by /// every operand bundle in this OperandBundleUser. unsigned getNumTotalBundleOperands() const { Index: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1362,7 +1362,16 @@ // FIXME: many arithmetic intrinsics have no issue taking a // variable, however it's hard to distingish these from // specials such as @llvm.frameaddress that require a constant. - return !isa(I); + if (isa(I)) + return false; + + // Constant bundle operands may need to retain their constant-ness for + // correctness. + if (ImmutableCallSite(I).isBundleOperand(OpIdx)) + return false; + + return true; + case Instruction::ShuffleVector: // Shufflevector masks are constant. return OpIdx != 2; Index: llvm/trunk/test/Transforms/SimplifyCFG/sink-common-code.ll =================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/sink-common-code.ll +++ llvm/trunk/test/Transforms/SimplifyCFG/sink-common-code.ll @@ -755,6 +755,32 @@ ; CHECK-NOT: exact ; CHECK: } +declare i32 @call_target() + +define void @test_operand_bundles(i1 %cond, i32* %ptr) { +entry: + br i1 %cond, label %left, label %right + +left: + %val0 = call i32 @call_target() [ "deopt"(i32 10) ] + store i32 %val0, i32* %ptr + br label %merge + +right: + %val1 = call i32 @call_target() [ "deopt"(i32 20) ] + store i32 %val1, i32* %ptr + br label %merge + +merge: + ret void +} + +; CHECK-LABEL: @test_operand_bundles( +; CHECK: left: +; CHECK-NEXT: %val0 = call i32 @call_target() [ "deopt"(i32 10) ] +; CHECK: right: +; CHECK-NEXT: %val1 = call i32 @call_target() [ "deopt"(i32 20) ] + ; CHECK: !0 = !{!1, !1, i64 0} ; CHECK: !1 = !{!"float", !2} ; CHECK: !2 = !{!"an example type tree"}