While working on improving forwprop and removal of forward_propagate_into_gimple_cond/forward_propagate_into_comparison, I came cross a case where we end up with SSA_NAME in the resulting gimple_match_op and one statement in the sequence. This was the result of simplification of: ``` _3 = MIN_EXPR <maxlen_2(D), 264> > 16 if (_3 > 16) ... ```
Which simplifies down to: (maxlen_2(D) > 16) & (264 > 16) into (maxlen_2(D) > 16) & 1 Which `maxlen_2(D) > 16` gets pushed onto the sequence and then the & 1 is removed via the match pattern: ``` /* x & ~0 -> x */ (simplify (bit_and @0 integer_all_onesp) (non_lvalue @0)) ``` So what this patch does is to undo the push extracting the new op from the pushed statement and remove the sequence as it is not used any more. Bootstrapped and tested on x86_64-linux-gnu. gcc/ChangeLog: PR tree-optimization/120331 * gimple-match-exports.cc (maybe_undo_push): New function. (gimple_simplify): Call maybe_undo_push if resimplify was successfull. Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com> --- gcc/gimple-match-exports.cc | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/gcc/gimple-match-exports.cc b/gcc/gimple-match-exports.cc index ccba046a1d4..b3acae21fa5 100644 --- a/gcc/gimple-match-exports.cc +++ b/gcc/gimple-match-exports.cc @@ -861,6 +861,28 @@ gimple_extract_op (gimple *stmt, gimple_match_op *res_op) return gimple_extract (stmt, res_op, nop, nop); } +/* In some cases, the resulting RES_OP might contain just a + SSA_NAME and the sequence SEQ contains one statement, we can + possibile undo the push and change the match RES_OP into + what the statement is. */ +static void +maybe_undo_push (gimple_seq *seq, gimple_match_op *res_op) +{ + if (!seq || !gimple_seq_singleton_p (*seq)) + return; + if (res_op->code != SSA_NAME) + return; + gimple *stmt = gimple_seq_first_stmt (*seq); + if (gimple_get_lhs (stmt) != res_op->ops[0]) + return; + gimple_match_op new_op; + if (!gimple_extract_op (stmt, &new_op)) + return; + gimple_seq_discard (*seq); + *seq = NULL; + *res_op = new_op; +} + /* The main STMT based simplification entry. It is used by the fold_stmt and the fold_stmt_to_constant APIs. */ @@ -917,7 +939,10 @@ gimple_simplify (gimple *stmt, gimple_match_op *res_op, gimple_seq *seq, if (!res_op->reverse && res_op->num_ops && res_op->resimplify (seq, valueize)) - return true; + { + maybe_undo_push (seq, res_op); + return true; + } return valueized; } -- 2.43.0