diff options
author | Roger Sayle <roger@nextmovesoftware.com> | 2021-06-11 17:15:38 +0100 |
---|---|---|
committer | Roger Sayle <roger@nextmovesoftware.com> | 2021-06-11 17:17:58 +0100 |
commit | 5b02ed4b87685c0f7c5da9b46cde3ce56fcfd457 (patch) | |
tree | 5383dd4f566eb945a79017ed6c292af4f627257c /gcc/match.pd | |
parent | b8b80b8aa3d9a7abbcb59b651ea5e84c2ea12d0b (diff) | |
download | gcc-5b02ed4b87685c0f7c5da9b46cde3ce56fcfd457.zip gcc-5b02ed4b87685c0f7c5da9b46cde3ce56fcfd457.tar.gz gcc-5b02ed4b87685c0f7c5da9b46cde3ce56fcfd457.tar.bz2 |
[PATCH] PR tree-optimization/96392 Optimize x+0.0 if x is an integer
The patch implements a missed optimization enhancement. Under usual
IEEE rules, x+0.0 can't be simplified to x when x might potentially
be an IEEE minus zero (-0.0). The current logic in the middle-end
checks whether the type of x should honor signed zeros, but with this
patch we introduce tree_expr_maybe_real_minus_zero_p that allows us
to confirm that the value can't possibly be -0.0, for example, the result
of a conversion from an integer type, or the result of fabs (or has a
type that doesn't honor signed zero).
Whilst modifying match.pd, I also converted some additional folding
transformations from "testing the type" to "testing the value".
2020-06-10 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
PR tree-optimization/96392
* fold-const.c (fold_real_zero_addition_p): Take both arguments
of the addition or subtraction, not just the zero. Use this
other argument in tests for signaling NaNs and signed zeros.
(tree_expr_maybe_real_minus_zero_p): New predicate.
* fold-const.h (fold_real_zero_addition_p): Update prototype.
(tree_expr_maybe_real_minus_zero_p): New function prototype.
* match.pd: Update calls to fold_real_zero_addition_p.
Replace HONOR_NANS with tree_expr_maybe_nan_p.
Replace HONOR_SIGNED_ZEROS with tree_expr_maybe_real_minus_zero_p.
Replace HONOR_SNANS with tree_expr_maybe_signaling_nan_p.
* tree-ssa-reassoc.c (eliminate_using_constants): Update
call to fold_real_zero_addition_p.
gcc/testsuite/ChangeLog
PR tree-optimization/96392
* gcc.dg/pr96392.c: New test.
Diffstat (limited to 'gcc/match.pd')
-rw-r--r-- | gcc/match.pd | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index bf22bc3..39fb57e 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -152,13 +152,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) Likewise if the operands are reversed. */ (simplify (plus:c @0 real_zerop@1) - (if (fold_real_zero_addition_p (type, @1, 0)) + (if (fold_real_zero_addition_p (type, @0, @1, 0)) (non_lvalue @0))) /* See if ARG1 is zero and X - ARG1 reduces to X. */ (simplify (minus @0 real_zerop@1) - (if (fold_real_zero_addition_p (type, @1, 1)) + (if (fold_real_zero_addition_p (type, @0, @1, 1)) (non_lvalue @0))) /* Even if the fold_real_zero_addition_p can't simplify X + 0.0 @@ -190,7 +190,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) is volatile. */ (simplify (minus @0 @0) - (if (!FLOAT_TYPE_P (type) || !HONOR_NANS (type)) + (if (!FLOAT_TYPE_P (type) || !tree_expr_maybe_nan_p (@0)) { build_zero_cst (type); })) (simplify (pointer_diff @@0 @0) @@ -206,14 +206,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) negative value by 0 gives -0, not +0. */ (simplify (mult @0 real_zerop@1) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) + && !tree_expr_maybe_real_minus_zero_p (@0) + && !tree_expr_maybe_real_minus_zero_p (@1)) @1)) /* In IEEE floating point, x*1 is not equivalent to x for snans. Likewise for complex arithmetic with signed zeros. */ (simplify (mult @0 real_onep) - (if (!HONOR_SNANS (type) + (if (!tree_expr_maybe_signaling_nan_p (@0) && (!HONOR_SIGNED_ZEROS (type) || !COMPLEX_FLOAT_TYPE_P (type))) (non_lvalue @0))) @@ -221,7 +223,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Transform x * -1.0 into -x. */ (simplify (mult @0 real_minus_onep) - (if (!HONOR_SNANS (type) + (if (!tree_expr_maybe_signaling_nan_p (@0) && (!HONOR_SIGNED_ZEROS (type) || !COMPLEX_FLOAT_TYPE_P (type))) (negate @0))) @@ -259,7 +261,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Transform X * (X <= 0.0 ? 1.0 : -1.0) into -abs(X). */ (simplify (mult:c @0 (cond (cmp @0 real_zerop) real_onep@1 real_minus_onep)) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) && !HONOR_SIGNED_ZEROS (type)) (outp (abs @0)))) /* Transform X * (X > 0.0 ? -1.0 : 1.0) into -abs(X). */ /* Transform X * (X >= 0.0 ? -1.0 : 1.0) into -abs(X). */ @@ -267,19 +269,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Transform X * (X <= 0.0 ? -1.0 : 1.0) into abs(X). */ (simplify (mult:c @0 (cond (cmp @0 real_zerop) real_minus_onep real_onep@1)) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) && !HONOR_SIGNED_ZEROS (type)) (outn (abs @0))))) /* Transform X * copysign (1.0, X) into abs(X). */ (simplify (mult:c @0 (COPYSIGN_ALL real_onep @0)) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) && !HONOR_SIGNED_ZEROS (type)) (abs @0))) /* Transform X * copysign (1.0, -X) into -abs(X). */ (simplify (mult:c @0 (COPYSIGN_ALL real_onep (negate @0))) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) && !HONOR_SIGNED_ZEROS (type)) (negate (abs @0)))) /* Transform copysign (CST, X) into copysign (ABS(CST), X). */ @@ -444,13 +446,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* In IEEE floating point, x/1 is not equivalent to x for snans. */ (simplify (rdiv @0 real_onep) - (if (!HONOR_SNANS (type)) + (if (!tree_expr_maybe_signaling_nan_p (@0)) (non_lvalue @0))) /* In IEEE floating point, x/-1 is not equivalent to -x for snans. */ (simplify (rdiv @0 real_minus_onep) - (if (!HONOR_SNANS (type)) + (if (!tree_expr_maybe_signaling_nan_p (@0)) (negate @0))) (if (flag_reciprocal_math) @@ -3543,7 +3545,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (-ARG1 + ARG0) reduces to -ARG1. */ (simplify (minus real_zerop@0 @1) - (if (fold_real_zero_addition_p (type, @0, 0)) + (if (fold_real_zero_addition_p (type, @1, @0, 0)) (negate @1))) /* Transform x * -1 into -x. */ |