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)
>

Reply via email to