]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/114269 - 434.zeusmp regression after SCEV analysis fix
authorRichard Biener <rguenther@suse.de>
Fri, 8 Mar 2024 12:27:12 +0000 (13:27 +0100)
committerRichard Biener <rguenther@suse.de>
Fri, 8 Mar 2024 13:40:57 +0000 (14:40 +0100)
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.

PR tree-optimization/114269
PR tree-optimization/114074
* 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

index 2e6c7356d3be413d8ffb6888a217e2785d664872..7cd0ebc10102c02838c02dc90fbc54c9362e6712 100644 (file)
@@ -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 */