This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
real_zerop for vectors
- From: Marc Glisse <marc dot glisse at inria dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 28 Oct 2012 16:14:46 +0100 (CET)
- Subject: real_zerop for vectors
Hello,
this patch lets some predicates on floating point constants answer true
for vectors, so optimizations are applied.
Tested bootstrap + testsuite (default languages).
2012-10-29 Marc Glisse <marc.glisse@inria.fr>
PR middle-end/55027
gcc/
* tree.c (real_zerop, real_onep, real_twop, real_minus_onep):
Handle VECTOR_CST.
testsuite/
* gcc.dg/pr55027.c: New testcase.
--
Marc Glisse
Index: gcc/testsuite/gcc.dg/pr55027.c
===================================================================
--- gcc/testsuite/gcc.dg/pr55027.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr55027.c (revision 0)
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -fdump-tree-optimized-raw" } */
+
+typedef double v2df __attribute__ ((__vector_size__ (2 * sizeof (double))));
+
+void f (v2df *x)
+{
+ *x = 0 + 1 * *x;
+}
+
+/* { dg-final { scan-tree-dump-not "gimple_assign" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
Property changes on: gcc/testsuite/gcc.dg/pr55027.c
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision URL
Added: svn:eol-style
+ native
Index: gcc/tree.c
===================================================================
--- gcc/tree.c (revision 192894)
+++ gcc/tree.c (working copy)
@@ -1985,75 +1985,127 @@ tree_floor_log2 (const_tree expr)
}
/* Return 1 if EXPR is the real constant zero. Trailing zeroes matter for
decimal float constants, so don't return 1 for them. */
int
real_zerop (const_tree expr)
{
STRIP_NOPS (expr);
- return ((TREE_CODE (expr) == REAL_CST
- && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0)
- && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))))
- || (TREE_CODE (expr) == COMPLEX_CST
- && real_zerop (TREE_REALPART (expr))
- && real_zerop (TREE_IMAGPART (expr))));
+ switch (TREE_CODE (expr))
+ {
+ case REAL_CST:
+ return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0)
+ && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
+ case COMPLEX_CST:
+ return real_zerop (TREE_REALPART (expr))
+ && real_zerop (TREE_IMAGPART (expr));
+ case VECTOR_CST:
+ {
+ unsigned i;
+ for (i = 0; i < VECTOR_CST_NELTS (expr); ++i)
+ if (!real_zerop (VECTOR_CST_ELT (expr, i)))
+ return false;
+ return true;
+ }
+ default:
+ return false;
+ }
}
/* Return 1 if EXPR is the real constant one in real or complex form.
Trailing zeroes matter for decimal float constants, so don't return
1 for them. */
int
real_onep (const_tree expr)
{
STRIP_NOPS (expr);
- return ((TREE_CODE (expr) == REAL_CST
- && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1)
- && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))))
- || (TREE_CODE (expr) == COMPLEX_CST
- && real_onep (TREE_REALPART (expr))
- && real_zerop (TREE_IMAGPART (expr))));
+ switch (TREE_CODE (expr))
+ {
+ case REAL_CST:
+ return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1)
+ && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
+ case COMPLEX_CST:
+ return real_onep (TREE_REALPART (expr))
+ && real_zerop (TREE_IMAGPART (expr));
+ case VECTOR_CST:
+ {
+ unsigned i;
+ for (i = 0; i < VECTOR_CST_NELTS (expr); ++i)
+ if (!real_onep (VECTOR_CST_ELT (expr, i)))
+ return false;
+ return true;
+ }
+ default:
+ return false;
+ }
}
/* Return 1 if EXPR is the real constant two. Trailing zeroes matter
for decimal float constants, so don't return 1 for them. */
int
real_twop (const_tree expr)
{
STRIP_NOPS (expr);
- return ((TREE_CODE (expr) == REAL_CST
- && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2)
- && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))))
- || (TREE_CODE (expr) == COMPLEX_CST
- && real_twop (TREE_REALPART (expr))
- && real_zerop (TREE_IMAGPART (expr))));
+ switch (TREE_CODE (expr))
+ {
+ case REAL_CST:
+ return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2)
+ && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
+ case COMPLEX_CST:
+ return real_twop (TREE_REALPART (expr))
+ && real_zerop (TREE_IMAGPART (expr));
+ case VECTOR_CST:
+ {
+ unsigned i;
+ for (i = 0; i < VECTOR_CST_NELTS (expr); ++i)
+ if (!real_twop (VECTOR_CST_ELT (expr, i)))
+ return false;
+ return true;
+ }
+ default:
+ return false;
+ }
}
/* Return 1 if EXPR is the real constant minus one. Trailing zeroes
matter for decimal float constants, so don't return 1 for them. */
int
real_minus_onep (const_tree expr)
{
STRIP_NOPS (expr);
- return ((TREE_CODE (expr) == REAL_CST
- && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1)
- && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))))
- || (TREE_CODE (expr) == COMPLEX_CST
- && real_minus_onep (TREE_REALPART (expr))
- && real_zerop (TREE_IMAGPART (expr))));
+ switch (TREE_CODE (expr))
+ {
+ case REAL_CST:
+ return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1)
+ && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
+ case COMPLEX_CST:
+ return real_minus_onep (TREE_REALPART (expr))
+ && real_zerop (TREE_IMAGPART (expr));
+ case VECTOR_CST:
+ {
+ unsigned i;
+ for (i = 0; i < VECTOR_CST_NELTS (expr); ++i)
+ if (!real_minus_onep (VECTOR_CST_ELT (expr, i)))
+ return false;
+ return true;
+ }
+ default:
+ return false;
+ }
}
/* Nonzero if EXP is a constant or a cast of a constant. */
int
really_constant_p (const_tree exp)
{
/* This is not quite the same as STRIP_NOPS. It does more. */
while (CONVERT_EXPR_P (exp)
|| TREE_CODE (exp) == NON_LVALUE_EXPR)