https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111515
--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
So like the following which disables threading ending in a
if (..)
__builtin_unreachable ();
branch when we thread to the _reachable_ side of it. We keep threading
to the __builtin_unreachable () side as that might result in resolving
earlier branches on the path. It's going to be interesting to argue
that __builtin_abort () shouldn't be treated this way (but I think
__builtin_unreachable and __builtin_unreachable_trap should not differ
for QOI reasons?)
diff --git a/gcc/tree-ssa-threadbackward.cc b/gcc/tree-ssa-threadbackward.cc
index c45f4b261ad..22f6254cf98 100644
--- a/gcc/tree-ssa-threadbackward.cc
+++ b/gcc/tree-ssa-threadbackward.cc
@@ -878,6 +878,26 @@ back_threader_profitability::profitable_path_p (const
vec<basic_block> &m_path,
"non-empty latch\n");
return false;
}
+
+ /* We don't want to duplicate a path when the branch we resolve is
+ going to be elided anyway unless we figure the path is unreachable
+ itself. */
+ edge_iterator ei;
+ edge e;
+ gcall *call;
+ FOR_EACH_EDGE (e, ei, taken_edge->src->succs)
+ if (e != taken_edge
+ && (call = safe_as_a <gcall *> (*gsi_last_bb (e->dest)))
+ && (gimple_call_builtin_p (call, BUILT_IN_UNREACHABLE)
+ || gimple_call_builtin_p (call, BUILT_IN_UNREACHABLE_TRAP)))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ " FAIL: Thread ends on the reachable side of a branch "
+ "to unreachable\n");
+ return false;
+ }
+
if (dump_file && (dump_flags & TDF_DETAILS))
fputc ('\n', dump_file);
return true;