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