https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120280
--- Comment #11 from Richard Biener <rguenth at gcc dot gnu.org> --- Well, the issue is that tree_expr_nonnegative_p does not honor no_follow_ssa_edges in static bool cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi) { ... switch (gimple_code (stmt)) { case GIMPLE_COND: { gimple_match_op res_op; if (gimple_simplify (stmt, &res_op, NULL, no_follow_ssa_edges, no_follow_ssa_edges) && res_op.code == INTEGER_CST) val = res_op.ops[0]; this is done because we operate on a partially valid SSA form only. Esp. the PHI handling in gimple_stmt_nonnegative_warnv_p is problematic here. So I'd say match.pd should never use any of the SSA following predicates (and the more and more added helpers like bitwise_equal are equally problematic). In fact, we should try to get rid of those GIMPLE walks in predicates, _esp_ those walking of PHI edges. In the overall GCC design plan I've always wanted some kind of folding context - there we could eventually check for an active no_follow_ssa_edges or other valueization hook. But apart from some ad-hoc partial conversion by adding some global "fold_context" pointer (and possibly ways to stack them, like we can with the gimplify context), this is a lot of work. Now, another idea might be to add (define_predicate_with_valueization tree_expr_nonnegative_p) and have genmatch generate tree_expr_nonnegative_p (valueize, @0) calls, thus pass down such hook and handle the hook all the way down. The other thing is to at least try pruning the PHI handling of all those hooks and see whether we still need that. For the abs(x) >= 0 pattern you could, instead of using tree_expr_nonnegative_p, rely on get_range_query ()->range_of_expr () instead of the tree predicate. That works only on GIMPLE of course.