[SplitEdge] Update SplitCriticalEdge to return a nullptr only when the edge is not...
authorSidharth Baveja <sidharth.baveja@ibm.com>
Tue, 6 Apr 2021 21:24:40 +0000 (21:24 +0000)
committerSidharth Baveja <sidharth.baveja@ibm.com>
Tue, 6 Apr 2021 21:24:40 +0000 (21:24 +0000)
commitd81d9e8b8604c85709de0a22bb8dd672a28f0401
tree3f4bfa056b56a0e07c87b6f8872dcc361e9b61a1
parentc060945b23a1c54d4b2a053ff4b093a2277b303d
[SplitEdge] Update SplitCriticalEdge to return a nullptr only when the edge is not critical

Summary:
The function SplitCriticalEdge (called by SplitEdge) can return a nullptr in
cases where the edge is a critical. SplitEdge uses SplitCriticalEdge assuming it
can always split all critical edges, which is an incorrect assumption.

The three cases where the function SplitCriticalEdge will return a nullptr is:
1. DestBB is an exception block
2. Options.IgnoreUnreachableDests is set to true and
isa(DestBB->getFirstNonPHIOrDbgOrLifetime()) is not equal to a nullptr
3. LoopSimplify form must be preserved (Options.PreserveLoopSimplify is true)
and it cannot be maintained for a loop due to indirect branches

For each of these situations they are handled in the following way:
1. Modified the function ehAwareSplitEdge originally from
llvm/lib/Transforms/Coroutines/CoroFrame.cpp to handle the cases when the DestBB
is an exception block. This function is called directly in SplitEdge.
SplitEdge does not call SplitCriticalEdge in this case
2. Options.IgnoreUnreachableDests is set to false by default, so this situation
does not apply.
3. Return a nullptr in this situation since the SplitCriticalEdge also returned
nullptr. Nothing we can do in this case.

Reviewed By: asbirlea

Differential Revision:https://reviews.llvm.org/D94619
llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
llvm/lib/Transforms/Coroutines/CoroFrame.cpp
llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp
llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp