On Thu, Apr 25, 2013 at 11:47:02PM +0200, Jakub Jelinek wrote: > This patch adds folding of constant arguments v>> and v<<, which helps to > optimize the testcase from the PR back into constant store after vectorized > loop is unrolled.
As this fixes a regression on the 4.8 branch, I've backported it (and minimal prerequisite for that) to 4.8 branch too. As the non-whole vector shifts VECTOR_CST by INTEGER_CST don't have any testcase showing a regression, I've left those out (trunk has instead of that else return NULL_TREE; code to handle those). 2013-05-03 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2013-04-26 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/57051 * fold-const.c (const_binop): Handle VEC_LSHIFT_EXPR and VEC_RSHIFT_EXPR if shift count is a multiple of element bitsize. 2013-04-12 Marc Glisse <marc.gli...@inria.fr> * fold-const.c (fold_binary_loc): Call const_binop also for mixed vector-scalar operations. --- gcc/fold-const.c (revision 198579) +++ gcc/fold-const.c (working copy) @@ -1366,6 +1366,44 @@ const_binop (enum tree_code code, tree a return build_vector (type, elts); } + + /* Shifts allow a scalar offset for a vector. */ + if (TREE_CODE (arg1) == VECTOR_CST + && TREE_CODE (arg2) == INTEGER_CST) + { + tree type = TREE_TYPE (arg1); + int count = TYPE_VECTOR_SUBPARTS (type), i; + tree *elts = XALLOCAVEC (tree, count); + + if (code == VEC_LSHIFT_EXPR + || code == VEC_RSHIFT_EXPR) + { + if (!host_integerp (arg2, 1)) + return NULL_TREE; + + unsigned HOST_WIDE_INT shiftc = tree_low_cst (arg2, 1); + unsigned HOST_WIDE_INT outerc = tree_low_cst (TYPE_SIZE (type), 1); + unsigned HOST_WIDE_INT innerc + = tree_low_cst (TYPE_SIZE (TREE_TYPE (type)), 1); + if (shiftc >= outerc || (shiftc % innerc) != 0) + return NULL_TREE; + int offset = shiftc / innerc; + if (code == VEC_LSHIFT_EXPR) + offset = -offset; + tree zero = build_zero_cst (TREE_TYPE (type)); + for (i = 0; i < count; i++) + { + if (i + offset < 0 || i + offset >= count) + elts[i] = zero; + else + elts[i] = VECTOR_CST_ELT (arg1, i + offset); + } + } + else + return NULL_TREE; + + return build_vector (type, elts); + } return NULL_TREE; } @@ -9862,7 +9900,8 @@ fold_binary_loc (location_t loc, || (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) { Jakub