public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-3824] More NEGATE_EXPR folding in match.pd
@ 2021-09-22 18:19 Roger Sayle
0 siblings, 0 replies; only message in thread
From: Roger Sayle @ 2021-09-22 18:19 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:8f571e64713cc72561f84241863496e473eae4c6
commit r12-3824-g8f571e64713cc72561f84241863496e473eae4c6
Author: Roger Sayle <roger@nextmovesoftware.com>
Date: Wed Sep 22 19:17:49 2021 +0100
More NEGATE_EXPR folding in match.pd
As observed by Jakub in comment #2 of PR 98865, the expression -(a>>63)
is optimized in GENERIC but not in GIMPLE. Investigating further it
turns out that this is one of a few transformations performed by
fold_negate_expr in fold-const.c that aren't yet performed by match.pd.
This patch moves/duplicates them there, and should be relatively safe
as these transformations are already performed by the compiler, but
just in different passes.
This revised patch adds a Boolean simplify argument to tree-ssa-sccvn.c's
vn_nary_build_or_lookup_1 to control whether simplification should be
performed before value numbering, updating the callers, but then
avoiding simplification when constructing/value-numbering NEGATE_EXPR.
This avoids the regression of gcc.dg/tree-ssa/ssa-free-88.c, and enables
the new test case(s) to pass.
2021-09-22 Roger Sayle <roger@nextmovesoftware.com>
Richard Biener <rguenther@suse.de>
gcc/ChangeLog
* match.pd (negation simplifications): Implement some negation
folding transformations from fold-const.c's fold_negate_expr.
* tree-ssa-sccvn.c (vn_nary_build_or_lookup_1): Add a SIMPLIFY
argument, to control whether the op should be simplified prior
to looking up/assigning a value number.
(vn_nary_build_or_lookup): Update call to vn_nary_build_or_lookup_1.
(vn_nary_simplify): Likewise.
(visit_nary_op): Likewise, but when constructing a NEGATE_EXPR
now call vn_nary_build_or_lookup_1 disabling simplification.
gcc/testsuite/ChangeLog
* gcc.dg/fold-negate-1.c: New test case.
Diff:
---
gcc/match.pd | 30 +++++++++++++++++++
gcc/testsuite/gcc.dg/fold-negate-1.c | 58 ++++++++++++++++++++++++++++++++++++
gcc/tree-ssa-sccvn.c | 35 ++++++++++++----------
3 files changed, 107 insertions(+), 16 deletions(-)
diff --git a/gcc/match.pd b/gcc/match.pd
index a063a1577b5..a9791ceb74a 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1481,6 +1481,36 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (!FIXED_POINT_TYPE_P (type))
(plus @0 (negate @1))))
+/* Other simplifications of negation (c.f. fold_negate_expr_1). */
+(simplify
+ (negate (mult:c@0 @1 negate_expr_p@2))
+ (if (! TYPE_UNSIGNED (type)
+ && ! HONOR_SIGN_DEPENDENT_ROUNDING (type)
+ && single_use (@0))
+ (mult @1 (negate @2))))
+
+(simplify
+ (negate (rdiv@0 @1 negate_expr_p@2))
+ (if (! HONOR_SIGN_DEPENDENT_ROUNDING (type)
+ && single_use (@0))
+ (rdiv @1 (negate @2))))
+
+(simplify
+ (negate (rdiv@0 negate_expr_p@1 @2))
+ (if (! HONOR_SIGN_DEPENDENT_ROUNDING (type)
+ && single_use (@0))
+ (rdiv (negate @1) @2)))
+
+/* Fold -((int)x >> (prec - 1)) into (unsigned)x >> (prec - 1). */
+(simplify
+ (negate (convert? (rshift @0 INTEGER_CST@1)))
+ (if (tree_nop_conversion_p (type, TREE_TYPE (@0))
+ && wi::to_wide (@1) == element_precision (type) - 1)
+ (with { tree stype = TREE_TYPE (@0);
+ tree ntype = TYPE_UNSIGNED (stype) ? signed_type_for (stype)
+ : unsigned_type_for (stype); }
+ (convert (rshift:ntype (convert:ntype @0) @1)))))
+
/* Try to fold (type) X op CST -> (type) (X op ((type-x) CST))
when profitable.
For bitwise binary operations apply operand conversions to the
diff --git a/gcc/testsuite/gcc.dg/fold-negate-1.c b/gcc/testsuite/gcc.dg/fold-negate-1.c
new file mode 100644
index 00000000000..00ec8b4c0b9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-negate-1.c
@@ -0,0 +1,58 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#define SHIFT ((8*__SIZEOF_INT__)-1)
+
+int test_rshift_1(int x)
+{
+ int t = x >> SHIFT;
+ return -t;
+}
+
+int test_rshift_2(int x)
+{
+ unsigned int t = (unsigned int)x >> SHIFT;
+ return -t;
+}
+
+int test_rshift_3(int x)
+{
+ int t = (unsigned int)x >> SHIFT;
+ return -t;
+}
+
+int test_rshift_4(int x)
+{
+ unsigned int t = x >> SHIFT;
+ return -t;
+}
+
+double test_mul_1(double x)
+{
+ double t = -5.0 * x;
+ return -t;
+}
+
+double test_mul_2(double x, double y)
+{
+ double t1 = -x;
+ double t2 = t1 * y;
+ return -t2;
+}
+
+double test_rdiv_1(double x, double y)
+{
+ double t1 = -x;
+ double t2 = t1 / y;
+ return -t2;
+}
+
+double test_rdiv_2(double x, double y)
+{
+ double t1 = -y;
+ double t2 = x / t1;
+ return -t2;
+}
+
+/* { dg-final { scan-tree-dump-not " -" "optimized" } } */
+
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index bfa516b6cf9..a901f51a025 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -2321,11 +2321,13 @@ vn_reference_lookup_or_insert_for_pieces (tree vuse,
}
/* Return a value-number for RCODE OPS... either by looking up an existing
- value-number for the simplified result or by inserting the operation if
- INSERT is true. */
+ value-number for the possibly simplified result or by inserting the
+ operation if INSERT is true. If SIMPLIFY is false, return a value
+ number for the unsimplified expression. */
static tree
-vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert)
+vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert,
+ bool simplify)
{
tree result = NULL_TREE;
/* We will be creating a value number for
@@ -2333,15 +2335,16 @@ vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert)
So first simplify and lookup this expression to see if it
is already available. */
/* For simplification valueize. */
- unsigned i;
- for (i = 0; i < res_op->num_ops; ++i)
- if (TREE_CODE (res_op->ops[i]) == SSA_NAME)
- {
- tree tem = vn_valueize (res_op->ops[i]);
- if (!tem)
- break;
- res_op->ops[i] = tem;
- }
+ unsigned i = 0;
+ if (simplify)
+ for (i = 0; i < res_op->num_ops; ++i)
+ if (TREE_CODE (res_op->ops[i]) == SSA_NAME)
+ {
+ tree tem = vn_valueize (res_op->ops[i]);
+ if (!tem)
+ break;
+ res_op->ops[i] = tem;
+ }
/* If valueization of an operand fails (it is not available), skip
simplification. */
bool res = false;
@@ -2440,7 +2443,7 @@ vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert)
static tree
vn_nary_build_or_lookup (gimple_match_op *res_op)
{
- return vn_nary_build_or_lookup_1 (res_op, true);
+ return vn_nary_build_or_lookup_1 (res_op, true, true);
}
/* Try to simplify the expression RCODE OPS... of type TYPE and return
@@ -2454,7 +2457,7 @@ vn_nary_simplify (vn_nary_op_t nary)
gimple_match_op op (gimple_match_cond::UNCOND, nary->opcode,
nary->type, nary->length);
memcpy (op.ops, nary->op, sizeof (tree) * nary->length);
- return vn_nary_build_or_lookup_1 (&op, false);
+ return vn_nary_build_or_lookup_1 (&op, false, true);
}
/* Elimination engine. */
@@ -5006,7 +5009,7 @@ visit_nary_op (tree lhs, gassign *stmt)
tree ops[2];
gimple_match_op match_op (gimple_match_cond::UNCOND,
NEGATE_EXPR, type, rhs[i]);
- ops[i] = vn_nary_build_or_lookup_1 (&match_op, false);
+ ops[i] = vn_nary_build_or_lookup_1 (&match_op, false, true);
ops[j] = rhs[j];
if (ops[i]
&& (ops[0] = vn_nary_op_lookup_pieces (2, code,
@@ -5014,7 +5017,7 @@ visit_nary_op (tree lhs, gassign *stmt)
{
gimple_match_op match_op (gimple_match_cond::UNCOND,
NEGATE_EXPR, type, ops[0]);
- result = vn_nary_build_or_lookup (&match_op);
+ result = vn_nary_build_or_lookup_1 (&match_op, true, false);
if (result)
{
bool changed = set_ssa_val_to (lhs, result);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-09-22 18:19 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-22 18:19 [gcc r12-3824] More NEGATE_EXPR folding in match.pd Roger Sayle
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).