This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR84067
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 27 Mar 2018 13:44:13 +0200 (CEST)
- Subject: [PATCH] Fix PR84067
The following guards the fold_plusminus_mult patterns with explicit
single_use checks to avoid regressing gcc.dg/wmul-1.c, that is,
introduction of additional multiplications.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
I've checked with a cross to aarch64 that the FAIL is gone.
Richard.
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.
Index: gcc/match.pd
===================================================================
--- gcc/match.pd (revision 258871)
+++ gcc/match.pd (working copy)
@@ -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(). */