Howdy.

In the backwards threader we attempt to thread paths that lead to a basic block ending in either a GIMPLE_COND, GIMPLE_SWITCH, or a GIMPLE_GOTO. The latter doesn't make much sense, since we only handle constants. What does a goto to a constant mean? Does that ever happen?

In tree-ssa-threadbackward.c, given a constant ARG, we attempt to find the taken edge out of a BB with find_taken_edge():

  edge taken_edge = find_taken_edge (path[0], arg);

But if we drill down into find_taken_edge, we can see that we don't even handle an ARG of a constant, only an ARGs of ADDR_EXPR or LABEL_EXPR:

  if (computed_goto_p (stmt))
    {
...
...
      if (val
          && (TREE_CODE (val) == ADDR_EXPR || TREE_CODE (val) == LABEL_EXPR)
          && TREE_CODE (TREE_OPERAND (val, 0)) == LABEL_DECL)
        return find_taken_edge_computed_goto (bb, TREE_OPERAND (val, 0));
      return NULL;
    }
  gcc_unreachable ();

I even tried bootstrapping and regtesting with:

diff --git a/gcc/tree-ssa-threadbackward.c b/gcc/tree-ssa-threadbackward.c
index 12bc80350f5..e80fba91ffd 100644
--- a/gcc/tree-ssa-threadbackward.c
+++ b/gcc/tree-ssa-threadbackward.c
@@ -301,6 +301,8 @@ profitable_jump_thread_path (vec<basic_block> &path,

      We have to know the outgoing edge to figure this out.  */
   edge taken_edge = find_taken_edge (path[0], arg);
+  if (taken_edge)
+    gcc_assert (gimple_code (stmt) != GIMPLE_GOTO);


...and this was never triggered.

Am I missing something fundamental here, or can we get rid of all the GIMPLE_GOTO handling in the backwards threader?

Thanks.
Aldy

Reply via email to