Hello,here is a patch to handle constant folding of mixed vector-integer operations. I could have shared the loop with the vector-vector case, but that would have meant re-testing if arg2 was a vector at every iteration (I can go back to that version if you prefer).
bootstrap+testsuite on x86_64-linux-gnu 2013-04-11 Marc Glisse <marc.gli...@inria.fr> gcc/ * fold-const.c (const_binop): Handle vector shifts by a scalar. (fold_binary_loc): Call const_binop also for mixed vector-scalar operations. gcc/testsuite/ * gcc.dg/fold-cstvecshift.c: New testcase. -- Marc Glisse
Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 197797) +++ gcc/fold-const.c (working copy) @@ -1335,34 +1335,56 @@ const_binop (enum tree_code code, tree a return NULL_TREE; } if (real && imag) return build_complex (type, real, imag); } if (TREE_CODE (arg1) == VECTOR_CST && TREE_CODE (arg2) == VECTOR_CST) { - tree type = TREE_TYPE(arg1); + tree type = TREE_TYPE (arg1); int count = TYPE_VECTOR_SUBPARTS (type), i; tree *elts = XALLOCAVEC (tree, count); for (i = 0; i < count; i++) { tree elem1 = VECTOR_CST_ELT (arg1, i); tree elem2 = VECTOR_CST_ELT (arg2, i); elts[i] = const_binop (code, elem1, elem2); /* It is possible that const_binop cannot handle the given code and return NULL_TREE */ - if(elts[i] == NULL_TREE) + if (elts[i] == NULL_TREE) + return NULL_TREE; + } + + return build_vector (type, elts); + } + + /* Shifts allow a scalar offset for a vector. */ + if (TREE_CODE (arg1) == VECTOR_CST) + { + tree type = TREE_TYPE (arg1); + int count = TYPE_VECTOR_SUBPARTS (type), i; + tree *elts = XALLOCAVEC (tree, count); + + for (i = 0; i < count; i++) + { + tree elem1 = VECTOR_CST_ELT (arg1, i); + + elts[i] = const_binop (code, elem1, arg2); + + /* It is possible that const_binop cannot handle the given + code and return NULL_TREE */ + if (elts[i] == NULL_TREE) return NULL_TREE; } return build_vector (type, elts); } return NULL_TREE; } /* Create a sizetype INT_CST node with NUMBER sign extended. KIND indicates which particular sizetype to create. */ @@ -9852,21 +9874,22 @@ fold_binary_loc (location_t loc, STRIP_NOPS (arg1); } /* Note that TREE_CONSTANT isn't enough: static var addresses are constant but we can't do arithmetic on them. */ if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST) || (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST) || (TREE_CODE (arg0) == FIXED_CST && TREE_CODE (arg1) == FIXED_CST) || (TREE_CODE (arg0) == FIXED_CST && TREE_CODE (arg1) == INTEGER_CST) || (TREE_CODE (arg0) == COMPLEX_CST && TREE_CODE (arg1) == COMPLEX_CST) - || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST)) + || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST) + || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == INTEGER_CST)) { if (kind == tcc_binary) { /* Make sure type and arg0 have the same saturating flag. */ gcc_assert (TYPE_SATURATING (type) == TYPE_SATURATING (TREE_TYPE (arg0))); tem = const_binop (code, arg0, arg1); } else if (kind == tcc_comparison) tem = fold_relational_const (code, type, arg0, arg1); Index: gcc/testsuite/gcc.dg/fold-cstvecshift.c =================================================================== --- gcc/testsuite/gcc.dg/fold-cstvecshift.c (revision 0) +++ gcc/testsuite/gcc.dg/fold-cstvecshift.c (revision 0) @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-ccp1" } */ + +typedef int vec __attribute__ ((vector_size (4 * sizeof (int)))); + +void f (vec *r) +{ + vec a = { 2, 3, 4, 5 }; + *r = (a << 2) >> 1; +} + +/* { dg-final { scan-tree-dump "{ 4, 6, 8, 10 }" "ccp1"} } */ +/* { dg-final { cleanup-tree-dump "ccp1" } } */ Property changes on: gcc/testsuite/gcc.dg/fold-cstvecshift.c ___________________________________________________________________ Added: svn:eol-style + native Added: svn:keywords + Author Date Id Revision URL