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 (); + } + 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.