From: Jakub Jelinek Date: Fri, 26 Apr 2013 13:13:36 +0000 (+0200) Subject: re PR tree-optimization/57051 (Optimization regression in 4.8.0 from 4.7.2) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=41e106896a657b1a5276559f243c9cfe39c67f83;p=gcc.git re PR tree-optimization/57051 (Optimization regression in 4.8.0 from 4.7.2) 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. From-SVN: r198339 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dd490374f52..bd5c8f1ef0b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2013-04-26 Jakub Jelinek + + 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-26 Richard Biener * omp-low.c (finalize_task_copyfn): Do not drop PROP_loops. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 59dbc034c4f..f93ce8a7e26 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -1380,17 +1380,42 @@ const_binop (enum tree_code code, tree arg1, tree arg2) int count = TYPE_VECTOR_SUBPARTS (type), i; tree *elts = XALLOCAVEC (tree, count); - for (i = 0; i < count; i++) + if (code == VEC_LSHIFT_EXPR + || code == VEC_RSHIFT_EXPR) { - tree elem1 = VECTOR_CST_ELT (arg1, i); - - elts[i] = const_binop (code, elem1, arg2); + if (!host_integerp (arg2, 1)) + return NULL_TREE; - /* It is possible that const_binop cannot handle the given - code and return NULL_TREE */ - if (elts[i] == 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 + 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); }