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;

Attachment: rb14938.patch
Description: rb14938.patch

Reply via email to