Hi, I think it was lost along the way that I did post an update to the detection code to fix the regression 😊 I think I have a better understanding of the code now and have updated the patch. Essentially when a signed comparison is encountered my match.pd pattern will trigger for EQ and NE. It rewrites these by inserting an unsigned cast and does a unsigned comparison With a modified immediate. The spaceship operator is looking for (res & 1) == res which was previously folded to (res & ~1) == 0. This is now being folded further to ((unsigned) res) <= 1. Given this this patch adds additional checks for when the value is an unsigned type conversion and the comparison value on the rhs is 1. Since the match.pd pattern rewrites this to either LE or GT those are the only two conditions I accept with a rhs of 1 for and then set the appropriate resulting comparison based on what I understand the spaceship operator to be doing. This fixes the regression and gets the same codegen as before. Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu and no regressions. Ok for master? Thanks, Tamar gcc/ChangeLog: * tree-ssa-phiopt.c (spaceship_replacement): Handle new canonical codegen. --- inline copy of patch --- diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 0e339c46afa29fa97f90d9bc4394370cd9b4b396..1a2f9294e5c3e6a7fd5ade4c21cdedc44e70d911 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -2038,6 +2038,26 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb, gimple *orig_use_stmt = use_stmt; tree orig_use_lhs = NULL_TREE; int prec = TYPE_PRECISION (TREE_TYPE (phires)); + + /* Deal with if match.pd has rewritten the (res & ~1) == 0 + into res <= 1 and has left a type-cast for signed types. */ + if (gimple_assign_cast_p (use_stmt)) + { + orig_use_lhs = gimple_assign_lhs (use_stmt); + /* Match.pd would have only done this for a signed type, + so the conversion must be to an unsigned one. */ + if (!TYPE_UNSIGNED (TREE_TYPE (orig_use_lhs))) + return false; + if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_use_lhs)) + return false; + if (EDGE_COUNT (phi_bb->preds) != 4) + return false; + if (!TYPE_UNSIGNED (TREE_TYPE (orig_use_lhs))) + return false; + if (!single_imm_use (orig_use_lhs, &use_p, &use_stmt)) + return false; + } + if (is_gimple_assign (use_stmt) && gimple_assign_rhs_code (use_stmt) == BIT_AND_EXPR && TREE_CODE (gimple_assign_rhs2 (use_stmt)) == INTEGER_CST @@ -2099,7 +2119,7 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb, || !tree_fits_shwi_p (rhs) || !IN_RANGE (tree_to_shwi (rhs), -1, 1)) return false; - if (orig_use_lhs) + if (orig_use_lhs && !integer_onep (rhs)) { if ((cmp != EQ_EXPR && cmp != NE_EXPR) || !integer_zerop (rhs)) return false; @@ -2345,6 +2365,8 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb, res_cmp = one_cmp == LT_EXPR ? GE_EXPR : LE_EXPR; else if (integer_minus_onep (rhs)) res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR; + else if (integer_onep (rhs)) + res_cmp = GE_EXPR; else return false; break; @@ -2353,6 +2375,8 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb, res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR; else if (integer_zerop (rhs)) res_cmp = one_cmp; + else if (integer_onep (rhs)) + res_cmp = one_cmp; else return false; break; @@ -2360,7 +2384,7 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb, if (integer_zerop (rhs)) res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR; else if (integer_onep (rhs)) - res_cmp = one_cmp; + res_cmp = LE_EXPR; else return false; break;