On Sun, Mar 31, 2013 at 6:31 AM, Marc Glisse <marc.gli...@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.gli...@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. > >