diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -7366,9 +7366,8 @@ establishes an association with additional labels to define where control flow goes after the call. -Outputs of a '``callbr``' instruction are valid only on the '``fallthrough``' -path. Use of outputs on the '``indirect``' path(s) results in :ref:`poison -values `. +The output values of a '``callbr``' instruction are available only to +the '``fallthrough``' block, not to any '``indirect``' blocks(s). The only use of this today is to implement the "goto" feature of gcc inline assembly where additional labels can be provided as locations for the inline diff --git a/llvm/lib/IR/Dominators.cpp b/llvm/lib/IR/Dominators.cpp --- a/llvm/lib/IR/Dominators.cpp +++ b/llvm/lib/IR/Dominators.cpp @@ -134,7 +134,7 @@ // dominates every instruction in UseBB. // A PHI is dominated only if the instruction dominates every possible use in // the UseBB. - if (isa(Def) || isa(User)) + if (isa(Def) || isa(Def) || isa(User)) return dominates(Def, UseBB); if (DefBB != UseBB) @@ -168,6 +168,13 @@ return dominates(E, UseBB); } + // Callbr results are similarly only usable in the default destination. + if (const auto *CBI = dyn_cast(Def)) { + BasicBlock *NormalDest = CBI->getDefaultDest(); + BasicBlockEdge E(DefBB, NormalDest); + return dominates(E, UseBB); + } + return dominates(DefBB, UseBB); } @@ -273,6 +280,13 @@ return dominates(E, U); } + // Callbr results are similarly only usable in the default destination. + if (const auto *CBI = dyn_cast(Def)) { + BasicBlock *NormalDest = CBI->getDefaultDest(); + BasicBlockEdge E(DefBB, NormalDest); + return dominates(E, U); + } + // If the def and use are in different blocks, do a simple CFG dominator // tree query. if (DefBB != UseBB) @@ -371,4 +385,3 @@ void DominatorTreeWrapperPass::print(raw_ostream &OS, const Module *) const { DT.print(OS); } -