On Sun, Oct 28, 2012 at 4:14 PM, Marc Glisse <marc.gli...@inria.fr> wrote: > Hello, > > this patch lets some predicates on floating point constants answer true for > vectors, so optimizations are applied. > > Tested bootstrap + testsuite (default languages).
Ok. Bonus points if you quickly eyed users of whether they may be surprised in vectors coming through now. Thanks, Richard. > 2012-10-29 Marc Glisse <marc.gli...@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) >