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;

Reply via email to