diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 16e69c0b0d0e21..207aacbad93e69 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1748,11 +1748,10 @@ static bool canSinkInstructions( !canReplaceOperandWithVariable(I0, OI)) // We can't create a PHI from this GEP. return false; - // Don't create indirect calls! The called value is the final operand. - if (isa(I0) && OI == OE - 1) { - // FIXME: if the call was *already* indirect, we should do this. + // Don't *create* indirect calls! The called value is the final operand. + auto *CB = dyn_cast(I0); + if (CB && OI == OE - 1 && !CB->isIndirectCall()) return false; - } for (auto *I : Insts) PHIOperands[I].push_back(I->getOperand(OI)); } diff --git a/llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll b/llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll index 917d1ab89eea9e..24f11b85bec539 100644 --- a/llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll +++ b/llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll @@ -1383,14 +1383,9 @@ if.end: define void @indirect_caller(i1 %c, i32 %v, void (i32)* %foo, void (i32)* %bar) { ; CHECK-LABEL: @indirect_caller( -; CHECK-NEXT: br i1 [[C:%.*]], label [[CALL_FOO:%.*]], label [[CALL_BAR:%.*]] -; CHECK: call_foo: -; CHECK-NEXT: tail call void [[FOO:%.*]](i32 [[V:%.*]]) -; CHECK-NEXT: br label [[END:%.*]] -; CHECK: call_bar: -; CHECK-NEXT: tail call void [[BAR:%.*]](i32 [[V]]) -; CHECK-NEXT: br label [[END]] -; CHECK: end: +; CHECK-NEXT: end: +; CHECK-NEXT: [[BAR_SINK:%.*]] = select i1 [[C:%.*]], void (i32)* [[FOO:%.*]], void (i32)* [[BAR:%.*]] +; CHECK-NEXT: tail call void [[BAR_SINK]](i32 [[V:%.*]]) ; CHECK-NEXT: ret void ; br i1 %c, label %call_foo, label %call_bar