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. 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