tree-optimization/114269 - 434.zeusmp regression after SCEV analysis fix

Message ID 20240308123107.D04A9138F4@imap2.dmz-prg2.suse.org
State Committed
Commit 018ddc86b928514d7dfee024dcdeb204d5dcdd61
Headers
Series tree-optimization/114269 - 434.zeusmp regression after SCEV analysis fix |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply

Commit Message

Richard Biener March 8, 2024, 12:31 p.m. UTC
  The following addresses a performance regression caused by the recent
SCEV analysis fix with regard to folding multiplications and undefined
behavior on overflow.  We do not handle (T) { a, +, b } * c but can
treat sign-conversions from unsigned by performing the multiplication
in the unsigned type.  That's what we already do for additions (but
that misses one case that turns out important).

This fixes the 434.zeusmp regression for me.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

	PR tree-optimization/114269
	* tree-chrec.cc (chrec_fold_plus_1): Handle sign-conversions
	in the third CASE_CONVERT case as well.
	(chrec_fold_multiply): Handle sign-conversions from unsigned
	by performing the operation in the unsigned type.
---
 gcc/tree-chrec.cc | 48 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)
  

Patch

diff --git a/gcc/tree-chrec.cc b/gcc/tree-chrec.cc
index 2e6c7356d3b..7cd0ebc1010 100644
--- a/gcc/tree-chrec.cc
+++ b/gcc/tree-chrec.cc
@@ -325,6 +325,22 @@  chrec_fold_plus_1 (enum tree_code code, tree type,
 				    : build_int_cst_type (type, -1)));
 
 	CASE_CONVERT:
+	  {
+	    /* We can strip sign-conversions to signed by performing the
+	       operation in unsigned.  */
+	    tree optype = TREE_TYPE (TREE_OPERAND (op1, 0));
+	    if (INTEGRAL_TYPE_P (type)
+		&& INTEGRAL_TYPE_P (optype)
+		&& tree_nop_conversion_p (type, optype)
+		&& TYPE_UNSIGNED (optype))
+	      return chrec_convert (type,
+				    chrec_fold_plus_1 (code, optype,
+						       chrec_convert (optype,
+								      op0, NULL),
+						       TREE_OPERAND (op1, 0)),
+				    NULL);
+	  }
+
 	  if (tree_contains_chrecs (op1, NULL))
 	    return chrec_dont_know;
 	  /* FALLTHRU */
@@ -424,6 +440,22 @@  chrec_fold_multiply (tree type,
 	  return chrec_fold_multiply_poly_poly (type, op0, op1);
 
 	CASE_CONVERT:
+	  {
+	    /* We can strip sign-conversions to signed by performing the
+	       operation in unsigned.  */
+	    tree optype = TREE_TYPE (TREE_OPERAND (op1, 0));
+	    if (INTEGRAL_TYPE_P (type)
+		&& INTEGRAL_TYPE_P (optype)
+		&& tree_nop_conversion_p (type, optype)
+		&& TYPE_UNSIGNED (optype))
+	      return chrec_convert (type,
+				    chrec_fold_multiply (optype,
+							 chrec_convert (optype,
+									op0, NULL),
+							 TREE_OPERAND (op1, 0)),
+				    NULL);
+	  }
+
 	  if (tree_contains_chrecs (op1, NULL))
 	    return chrec_dont_know;
 	  /* FALLTHRU */
@@ -474,6 +506,22 @@  chrec_fold_multiply (tree type,
 	}
 
     CASE_CONVERT:
+      {
+	/* We can strip sign-conversions to signed by performing the
+	   operation in unsigned.  */
+	tree optype = TREE_TYPE (TREE_OPERAND (op0, 0));
+	if (INTEGRAL_TYPE_P (type)
+	    && INTEGRAL_TYPE_P (optype)
+	    && tree_nop_conversion_p (type, optype)
+	    && TYPE_UNSIGNED (optype))
+	  return chrec_convert (type,
+				chrec_fold_multiply (optype,
+						     TREE_OPERAND (op0, 0),
+						     chrec_convert (optype,
+								    op1, NULL)),
+				NULL);
+      }
+
       if (tree_contains_chrecs (op0, NULL))
 	return chrec_dont_know;
       /* FALLTHRU */