This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Constant folding of VEC_COND_EXPR


On Sun, Mar 31, 2013 at 6:31 AM, Marc Glisse <marc.glisse@inria.fr> wrote:
> Hello,
>
> this adds constant folding of VEC_COND_EXPR at the tree level by forwarding
> to the VEC_PERM_EXPR code (a merge is a special case of a permutation). The
> CONSTRUCTOR case may be unreachable for now (it will probably need an extra
> piece of code in tree-ssa-forwprop.c), but it seems better to add it at the
> same time.
>
> bootstrap+testsuite on x86_64-linux-gnu.
>
> 2013-03-31  Marc Glisse  <marc.glisse@inria.fr>
>
>         PR tree-optimization/56790
>         * fold-const.c (fold_ternary_loc) <VEC_COND_EXPR>: Add constant
> folding.
>
> testsuite/
>         * g++.dg/ext/pr56790-1.C: New testcase.
>
> --
> Marc Glisse
> Index: gcc/testsuite/g++.dg/ext/pr56790-1.C
> ===================================================================
> --- gcc/testsuite/g++.dg/ext/pr56790-1.C        (revision 0)
> +++ gcc/testsuite/g++.dg/ext/pr56790-1.C        (revision 0)
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-ccp1" } */
> +
> +typedef long vec __attribute__ ((vector_size (2 * sizeof (long))));
> +
> +vec f (void)
> +{
> +  vec a = {  5,  7 };
> +  vec b = { 11, 13 };
> +  vec m = { -1,  0 };
> +  return m ? a : b;
> +}
> +
> +/* { dg-final { scan-tree-dump "{ 5, 13 }" "ccp1" } } */
> +/* { dg-final { scan-tree-dump-not "VEC_COND_EXPR" "ccp1" } } */
> +/* { dg-final { cleanup-tree-dump "ccp1" } } */
>
> Property changes on: gcc/testsuite/g++.dg/ext/pr56790-1.C
> ___________________________________________________________________
> Added: svn:keywords
>    + Author Date Id Revision URL
> Added: svn:eol-style
>    + native
>
> Index: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c    (revision 197284)
> +++ gcc/fold-const.c    (working copy)
> @@ -13917,20 +13917,43 @@ fold_ternary_loc (location_t loc, enum t
>                    || VOID_TYPE_P (type)))
>             return pedantic_non_lvalue_loc (loc, tem);
>           return NULL_TREE;
>         }
>        else if (TREE_CODE (arg0) == VECTOR_CST)
>         {
>           if (integer_all_onesp (arg0))
>             return pedantic_omit_one_operand_loc (loc, type, arg1, arg2);
>           if (integer_zerop (arg0))
>             return pedantic_omit_one_operand_loc (loc, type, arg2, arg1);
> +
> +         if ((TREE_CODE (arg1) == VECTOR_CST
> +              || TREE_CODE (arg1) == CONSTRUCTOR)
> +             && (TREE_CODE (arg2) == VECTOR_CST
> +                 || TREE_CODE (arg2) == CONSTRUCTOR))
> +           {
> +             unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
> +             unsigned char *sel = XALLOCAVEC (unsigned char, nelts);
> +             gcc_assert (nelts == VECTOR_CST_NELTS (arg0));
> +             for (i = 0; i < nelts; i++)
> +               {
> +                 tree val = VECTOR_CST_ELT (arg0, i);
> +                 if (integer_all_onesp (val))
> +                   sel[i] = i;
> +                 else if (integer_zerop (val))
> +                   sel[i] = nelts + i;
> +                 else
> +                   gcc_unreachable ();

I think this gcc_unreachable here is incorrect as it could cause an
internal compiler error for "target dependent code"
Try for:
typedef long vec __attribute__ ((vector_size (2 * sizeof (long))));

vec f (void)
{
  vec a = {  5,  7 };
  vec b = { 11, 13 };
  vec m = { 3,  2 };
  return m ? a : b;
}

I think for the above case we don't want to do any constant folding.

Thanks,
Andrew Pinski

> +               }
> +             tree t = fold_vec_perm (type, arg1, arg2, sel);
> +             if (t != NULL_TREE)
> +               return t;
> +           }
>         }
>
>        if (operand_equal_p (arg1, op2, 0))
>         return pedantic_omit_one_operand_loc (loc, type, arg1, arg0);
>
>        /* If we have A op B ? A : C, we may be able to convert this to a
>          simpler expression, depending on the operation and the values
>          of B and C.  Signed zeros prevent all of these transformations,
>          for reasons given above each one.
>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]