This is like the patch where we don't want to replace `bool_name != 0` with `bool_name` but for instead for INTEGER_CST. The only thing difference is there are a few different forms for always true/always false; only handle it if it was in the canonical form. A few new helpers are added for the canonical form detection.
This also replaces the previous version of the patch which did an early exit from fold_stmt_1 instead so we can change the non-canonical form into a canonical in the end. gcc/ChangeLog: * gimple.h (gimple_cond_true_canonical_p): New function. (gimple_cond_false_canonical_p): New function. * gimple-fold.cc (replace_stmt_with_simplification): Return false if replacing the operands of GIMPLE_COND with an INTEGER_CST and already in canonical form. Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com> --- gcc/gimple-fold.cc | 15 +++++++++++++-- gcc/gimple.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index f801e8b6d41..e63fd6f2f2f 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -6258,10 +6258,21 @@ replace_stmt_with_simplification (gimple_stmt_iterator *gsi, } else if (code == INTEGER_CST) { + /* Make into the canonical form `1 != 0` and `0 != 0`. + If already in the canonical form return false + saying nothing has been done. */ if (integer_zerop (ops[0])) - gimple_cond_make_false (cond_stmt); + { + if (gimple_cond_false_canonical_p (cond_stmt)) + return false; + gimple_cond_make_false (cond_stmt); + } else - gimple_cond_make_true (cond_stmt); + { + if (gimple_cond_true_canonical_p (cond_stmt)) + return false; + gimple_cond_make_true (cond_stmt); + } } else if (!inplace) { diff --git a/gcc/gimple.h b/gcc/gimple.h index 032365f3da2..977ff1c923c 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -3875,6 +3875,21 @@ gimple_cond_true_p (const gcond *gs) return false; } +/* Check if conditional statement GS is in the caonical form of 'if (1 != 0)'. */ + +inline bool +gimple_cond_true_canonical_p (const gcond *gs) +{ + tree lhs = gimple_cond_lhs (gs); + tree rhs = gimple_cond_rhs (gs); + tree_code code = gimple_cond_code (gs); + if (code == NE_EXPR + && lhs == boolean_true_node + && rhs == boolean_false_node) + return true; + return false; +} + /* Check if conditional statement GS is of the form 'if (1 != 1)', 'if (0 != 0)', 'if (1 == 0)' or 'if (0 == 1)' */ @@ -3900,6 +3915,21 @@ gimple_cond_false_p (const gcond *gs) return false; } +/* Check if conditional statement GS is in the caonical form of 'if (0 != 0)'. */ + +inline bool +gimple_cond_false_canonical_p (const gcond *gs) +{ + tree lhs = gimple_cond_lhs (gs); + tree rhs = gimple_cond_rhs (gs); + tree_code code = gimple_cond_code (gs); + if (code == NE_EXPR + && lhs == boolean_false_node + && rhs == boolean_false_node) + return true; + return false; +} + /* Set the code, LHS and RHS of GIMPLE_COND STMT from CODE, LHS and RHS. */ inline void -- 2.43.0