[PATCH] middle-end: fix de-optimizations with bitclear patterns on signed values

Tamar Christina Tamar.Christina@arm.com
Wed Nov 3 10:56:30 GMT 2021


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;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rb14938.patch
Type: application/octet-stream
Size: 2569 bytes
Desc: rb14938.patch
URL: <https://gcc.gnu.org/pipermail/gcc-patches/attachments/20211103/cdb1965c/attachment.obj>


More information about the Gcc-patches mailing list