On 04/19/2016 11:50 AM, Patrick Palka wrote:
1. This patch introduces a "regression" in gcc.dg/tree-ssa/ssa-thread-11.c
in that we no longer perform FSM threading during vrp2 but instead we
detect two new jump threading opportunities during vrp1. Not sure if
the new code is better but it is shorter. I wonder how this should be
resolved...
Definitely not a regression. As you note we thread two jumps earlier
utilizing your new code. With the old code we're dependent upon other
simplifications occurring which eventually exposes the FSM threads that
the test is checking for in vrp2.
I think we just want to remove the test for FSM jump threads in VRP2.
We get coverage for your test via ssa-thread-14. That should just leave
the verification that we do not have irreducible loops at the end of
VRP2 in ssa-thread-11. I'll make that change.
I do see what appears to be a missed jump thread, but that's not
affected positively or negatively by your change. There's a reasonable
chance it's only exposed by normal thread jumps in VRP2 and since we
don't iterate, it's left in the IL. I haven't analyzed it in detail,
but my hope is that when I pull the backwards threading out into its own
pass that we'll start picking up more of these secondary effects.
gcc/ChangeLog:
* tree-ssa-threadedge.c (simplify_control_stmt_condition): Split
out into ...
(simplify_control_stmt_condition_1): ... here. Recurse into
BIT_AND_EXPRs and BIT_IOR_EXPRs.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/ssa-thread-14.c: New test.
---
I fixed a few formatting nits (too long lines).
+
+ if (res1 != NULL_TREE && res2 != NULL_TREE)
+ {
+ if (rhs_code == BIT_AND_EXPR
+ && TYPE_PRECISION (TREE_TYPE (op0)) == 1
+ && integer_nonzerop (res1)
+ && integer_nonzerop (res2))
+ {
+ /* If A != 0 and B != 0 then (bool)(A | B) != 0 is true. */
+ if (cond_code == NE_EXPR)
+ return one_cst;
+ /* If A != 0 and B != 0 then (bool)(A | B) == 0 is false. */
+ if (cond_code == EQ_EXPR)
+ return zero_cst;
I think you wanted (A & B) in the two immediately preceding comments,
which I fixed.
I suspect there's other stuff we could do in this space, but you've
probably covered the most important cases.
+ /* Handle (A CMP B) CMP 0. */
+ else if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
+ == tcc_comparison)
+ {
+ tree rhs1 = gimple_assign_rhs1 (def_stmt);
+ tree rhs2 = gimple_assign_rhs2 (def_stmt);
+
+ tree_code new_cond = gimple_assign_rhs_code (def_stmt);
+ if (cond_code == EQ_EXPR)
+ new_cond = invert_tree_comparison (new_cond, false);
+
+ tree res
+ = simplify_control_stmt_condition_1 (e, def_stmt, avail_exprs_stack,
+ rhs1, new_cond, rhs2,
+ dummy_cond, simplify,
+ handle_dominating_asserts,
+ limit - 1);
+ if (res != NULL_TREE && is_gimple_min_invariant (res))
+ return res;
I was a bit confused by this case, but then realized that we already
narrowed COND_CODE to EQ_EXPR/NE_EXPR.
I made the minor edits noted above and committed the change.
Thanks,
Jeff