re PR middle-end/84067 (gcc.dg/wmul-1.c regression on aarch64 after r257077)
authorRichard Biener <rguenther@suse.de>
Tue, 27 Mar 2018 13:23:15 +0000 (13:23 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 27 Mar 2018 13:23:15 +0000 (13:23 +0000)
2018-03-27  Richard Biener  <rguenther@suse.de>

PR middle-ed/84067
* match.pd ((A * C) +- (B * C) -> (A+-B) * C): Guard with
explicit single_use checks.

From-SVN: r258881

gcc/ChangeLog
gcc/match.pd

index 55c1f279d685dcd376fbedbe7d862e214b2a2a58..b670c5da8bedb335a141835771bcf9269e1122d5 100644 (file)
@@ -1,3 +1,9 @@
+2018-03-27  Richard Biener  <rguenther@suse.de>
+
+       PR middle-ed/84067
+       * match.pd ((A * C) +- (B * C) -> (A+-B) * C): Guard with
+       explicit single_use checks.
+
 2018-03-27  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/85082
index f61c4d7440adc09f995f7f4eb0a148c62c02beb2..3e1636c41a45104c42ef153dd9db8a5426b0806f 100644 (file)
@@ -1948,30 +1948,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      && (!FLOAT_TYPE_P (type) || flag_associative_math))
  (for plusminus (plus minus)
   (simplify
-   (plusminus (mult:cs @0 @1) (mult:cs @0 @2))
-   (if (!ANY_INTEGRAL_TYPE_P (type)
-        || TYPE_OVERFLOW_WRAPS (type)
-        || (INTEGRAL_TYPE_P (type)
-           && tree_expr_nonzero_p (@0)
-           && expr_not_equal_to (@0, wi::minus_one (TYPE_PRECISION (type)))))
-    (mult (plusminus @1 @2) @0)))
-  /* We cannot generate constant 1 for fract.  */
-  (if (!ALL_FRACT_MODE_P (TYPE_MODE (type)))
-   (simplify
-    (plusminus @0 (mult:cs @0 @2))
-    (if (!ANY_INTEGRAL_TYPE_P (type)
+   (plusminus (mult:cs@3 @0 @1) (mult:cs@4 @0 @2))
+   (if ((!ANY_INTEGRAL_TYPE_P (type)
         || TYPE_OVERFLOW_WRAPS (type)
         || (INTEGRAL_TYPE_P (type)
             && tree_expr_nonzero_p (@0)
             && expr_not_equal_to (@0, wi::minus_one (TYPE_PRECISION (type)))))
+       /* If @1 +- @2 is constant require a hard single-use on either
+          original operand (but not on both).  */
+       && (single_use (@3) || single_use (@4)))
+    (mult (plusminus @1 @2) @0)))
+  /* We cannot generate constant 1 for fract.  */
+  (if (!ALL_FRACT_MODE_P (TYPE_MODE (type)))
+   (simplify
+    (plusminus @0 (mult:c@3 @0 @2))
+    (if ((!ANY_INTEGRAL_TYPE_P (type)
+         || TYPE_OVERFLOW_WRAPS (type)
+         || (INTEGRAL_TYPE_P (type)
+             && tree_expr_nonzero_p (@0)
+             && expr_not_equal_to (@0, wi::minus_one (TYPE_PRECISION (type)))))
+        && single_use (@3))
      (mult (plusminus { build_one_cst (type); } @2) @0)))
    (simplify
-    (plusminus (mult:cs @0 @2) @0)
-    (if (!ANY_INTEGRAL_TYPE_P (type)
-        || TYPE_OVERFLOW_WRAPS (type)
-        || (INTEGRAL_TYPE_P (type)
-            && tree_expr_nonzero_p (@0)
-            && expr_not_equal_to (@0, wi::minus_one (TYPE_PRECISION (type)))))
+    (plusminus (mult:c@3 @0 @2) @0)
+    (if ((!ANY_INTEGRAL_TYPE_P (type)
+         || TYPE_OVERFLOW_WRAPS (type)
+         || (INTEGRAL_TYPE_P (type)
+             && tree_expr_nonzero_p (@0)
+             && expr_not_equal_to (@0, wi::minus_one (TYPE_PRECISION (type)))))
+        && single_use (@3))
      (mult (plusminus @2 { build_one_cst (type); }) @0))))))
 
 /* Simplifications of MIN_EXPR, MAX_EXPR, fmin() and fmax().  */