> Am 14.05.2025 um 03:12 schrieb Andrew Pinski <quic_apin...@quicinc.com>:
>
> This moves the canonicalization of `bool==0` and `bool!=1` from
> forwprop to cleanupcfg. We will still need to call it from forwprop
> so we don't need to call forwprop a few times to fp comparisons in some
> cases (forwprop-16.c was added originally for this code even).
>
> This is the first step in removing forward_propagate_into_gimple_cond
> and forward_propagate_into_comparison.
>
> Bootstrapped and tested on x86_64-linux-gnu.
Ok
Richard
> gcc/ChangeLog:
>
> * tree-cfgcleanup.cc (canonicalize_bool_cond): New function.
> (cleanup_control_expr_graph): Call canonicalize_bool_cond for GIMPLE_COND.
> * tree-cfgcleanup.h (canonicalize_bool_cond): New declaration.
> * tree-ssa-forwprop.cc (forward_propagate_into_gimple_cond):
> Call canonicalize_bool_cond.
>
> Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>
> ---
> gcc/tree-cfgcleanup.cc | 39 +++++++++++++++++++++++++++++++++++++++
> gcc/tree-cfgcleanup.h | 1 +
> gcc/tree-ssa-forwprop.cc | 18 ++----------------
> 3 files changed, 42 insertions(+), 16 deletions(-)
>
> diff --git a/gcc/tree-cfgcleanup.cc b/gcc/tree-cfgcleanup.cc
> index 38a62499f93..66575393a44 100644
> --- a/gcc/tree-cfgcleanup.cc
> +++ b/gcc/tree-cfgcleanup.cc
> @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-into-ssa.h"
> #include "tree-cfgcleanup.h"
> #include "target.h"
> +#include "gimple-pretty-print.h"
>
>
> /* The set of blocks in that at least one of the following changes happened:
> @@ -123,6 +124,41 @@ convert_single_case_switch (gswitch *swtch,
> gimple_stmt_iterator &gsi)
> return true;
> }
>
> +/* Canonicalize _Bool == 0 and _Bool != 1 to _Bool != 0 of STMT in BB by
> + swapping edges of the BB. */
> +bool
> +canonicalize_bool_cond (gcond *stmt, basic_block bb)
> +{
> + tree rhs1 = gimple_cond_lhs (stmt);
> + tree rhs2 = gimple_cond_rhs (stmt);
> + enum tree_code code = gimple_cond_code (stmt);
> + if (code != EQ_EXPR && code != NE_EXPR)
> + return false;
> + if (TREE_CODE (TREE_TYPE (rhs1)) != BOOLEAN_TYPE
> + && (!INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
> + || TYPE_PRECISION (TREE_TYPE (rhs1)) != 1))
> + return false;
> +
> + /* Canonicalize _Bool == 0 and _Bool != 1 to _Bool != 0 by swapping edges.
> */
> + if (code == EQ_EXPR && !integer_zerop (rhs2))
> + return false;
> + if (code == NE_EXPR && !integer_onep (rhs2))
> + return false;
> +
> + gimple_cond_set_code (stmt, NE_EXPR);
> + gimple_cond_set_rhs (stmt, build_zero_cst (TREE_TYPE (rhs1)));
> + EDGE_SUCC (bb, 0)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);
> + EDGE_SUCC (bb, 1)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);
> +
> + if (dump_file)
> + {
> + fprintf (dump_file, " Swapped '");
> + print_gimple_expr (dump_file, stmt, 0);
> + fprintf (dump_file, "'\n");
> + }
> + return true;
> +}
> +
> /* Disconnect an unreachable block in the control expression starting
> at block BB. */
>
> @@ -146,6 +182,9 @@ cleanup_control_expr_graph (basic_block bb,
> gimple_stmt_iterator gsi)
> && convert_single_case_switch (as_a<gswitch *> (stmt), gsi))
> stmt = gsi_stmt (gsi);
>
> + if (gimple_code (stmt) == GIMPLE_COND)
> + canonicalize_bool_cond (as_a<gcond*> (stmt), bb);
> +
> fold_defer_overflow_warnings ();
> switch (gimple_code (stmt))
> {
> diff --git a/gcc/tree-cfgcleanup.h b/gcc/tree-cfgcleanup.h
> index 83c857fe33a..94b430e0c71 100644
> --- a/gcc/tree-cfgcleanup.h
> +++ b/gcc/tree-cfgcleanup.h
> @@ -28,5 +28,6 @@ extern bool delete_unreachable_blocks_update_callgraph
> (cgraph_node *dst_node,
> bool update_clones);
> extern unsigned clean_up_loop_closed_phi (function *);
> extern bool phi_alternatives_equal (basic_block, edge, edge);
> +extern bool canonicalize_bool_cond (gcond *stmt, basic_block bb);
>
> #endif /* GCC_TREE_CFGCLEANUP_H */
> diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
> index bd407ef8a69..d718d8f7faf 100644
> --- a/gcc/tree-ssa-forwprop.cc
> +++ b/gcc/tree-ssa-forwprop.cc
> @@ -579,22 +579,8 @@ forward_propagate_into_gimple_cond (gcond *stmt)
> return (cfg_changed || is_gimple_min_invariant (tmp)) ? 2 : 1;
> }
>
> - /* Canonicalize _Bool == 0 and _Bool != 1 to _Bool != 0 by swapping edges.
> */
> - if ((TREE_CODE (TREE_TYPE (rhs1)) == BOOLEAN_TYPE
> - || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
> - && TYPE_PRECISION (TREE_TYPE (rhs1)) == 1))
> - && ((code == EQ_EXPR
> - && integer_zerop (rhs2))
> - || (code == NE_EXPR
> - && integer_onep (rhs2))))
> - {
> - basic_block bb = gimple_bb (stmt);
> - gimple_cond_set_code (stmt, NE_EXPR);
> - gimple_cond_set_rhs (stmt, build_zero_cst (TREE_TYPE (rhs1)));
> - EDGE_SUCC (bb, 0)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);
> - EDGE_SUCC (bb, 1)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);
> - return 1;
> - }
> + if (canonicalize_bool_cond (stmt, gimple_bb (stmt)))
> + return 1;
>
> return 0;
> }
> --
> 2.43.0
>