In this PR we used WIDEN_SUM_EXPR to vectorise: short i, y; int sum; [...] for (i = x; i > 0; i--) sum += y;
with 4 ints and 8 shorts per vector. The problem was that we set the VF based only on the ints, then calculated the number of vector copies based on the shorts, giving 4/8. Previously that led to ncopies==0, but after r249897 we pick it up as an ICE. In this particular case we could vectorise the reduction by setting ncopies based on the output type rather than the input type, but it doesn't seem worth adding a special "optimisation" for such a pathological case. I think it's really an instance of the more general problem that we can't vectorise using combinations of (say) 64-bit and 128-bit vectors on targets that support both. Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? Richard 2018-04-09 Richard Sandiford <richard.sandif...@linaro.org> gcc/ PR tree-optimization/85286 * tree-vect-data-refs.c (vect_get_smallest_scalar_type): gcc/testsuite/ * gcc.dg/vect/pr85286.c: New test. Index: gcc/tree-vect-data-refs.c =================================================================== --- gcc/tree-vect-data-refs.c 2018-03-24 10:52:25.616823316 +0000 +++ gcc/tree-vect-data-refs.c 2018-04-09 18:44:09.676561821 +0100 @@ -132,6 +132,8 @@ vect_get_smallest_scalar_type (gimple *s if (is_gimple_assign (stmt) && (gimple_assign_cast_p (stmt) + || gimple_assign_rhs_code (stmt) == DOT_PROD_EXPR + || gimple_assign_rhs_code (stmt) == WIDEN_SUM_EXPR || gimple_assign_rhs_code (stmt) == WIDEN_MULT_EXPR || gimple_assign_rhs_code (stmt) == WIDEN_LSHIFT_EXPR || gimple_assign_rhs_code (stmt) == FLOAT_EXPR)) Index: gcc/testsuite/gcc.dg/vect/pr85286.c =================================================================== --- /dev/null 2018-04-08 19:55:28.217132277 +0100 +++ gcc/testsuite/gcc.dg/vect/pr85286.c 2018-04-09 18:44:09.675561881 +0100 @@ -0,0 +1,19 @@ +/* PR tree-optimization/45241 */ +/* { dg-do compile } */ +/* { dg-additional-options "--param scev-max-expr-complexity=0" } */ + +int +foo (short x) +{ + short i, y; + int sum; + + for (i = 0; i < x; i++) + y = x * i; + + for (i = x; i > 0; i--) + sum += y; + + return sum; +} +