Do not look at constant or external defs in reduction stmts to determine the reduction PHI vector type. Those are promoted/demoted as required.
This is another fragile area, I'll poke around a bit but nevertheless, bootstrap & regtest queued. Richard. 2018-11-13 Richard Biener <rguent...@suse.de> PR tree-optimization/87974 * tree-vect-loop.c (vectorizable_reduction): When computing the vectorized reduction PHI vector type ignore constant and external defs. * g++.dg/opt/pr87974.C: New testcase. Index: gcc/tree-vect-loop.c =================================================================== --- gcc/tree-vect-loop.c (revision 266061) +++ gcc/tree-vect-loop.c (working copy) @@ -6061,13 +6070,17 @@ vectorizable_reduction (stmt_vec_info st return true; gassign *reduc_stmt = as_a <gassign *> (reduc_stmt_info->stmt); + code = gimple_assign_rhs_code (reduc_stmt); for (unsigned k = 1; k < gimple_num_ops (reduc_stmt); ++k) { tree op = gimple_op (reduc_stmt, k); if (op == phi_result) continue; - if (k == 1 - && gimple_assign_rhs_code (reduc_stmt) == COND_EXPR) + if (k == 1 && code == COND_EXPR) + continue; + bool is_simple_use = vect_is_simple_use (op, loop_vinfo, &dt); + gcc_assert (is_simple_use); + if (dt == vect_constant_def || dt == vect_external_def) continue; if (!vectype_in || (GET_MODE_SIZE (SCALAR_TYPE_MODE (TREE_TYPE (vectype_in))) Index: gcc/testsuite/g++.dg/opt/pr87974.C =================================================================== --- gcc/testsuite/g++.dg/opt/pr87974.C (nonexistent) +++ gcc/testsuite/g++.dg/opt/pr87974.C (working copy) @@ -0,0 +1,33 @@ +// { dg-do compile } +// { dg-options "-O3" } + +struct h { + typedef int &c; +}; +class i { + struct j { + using c = int *; + }; + using as = j::c; +}; +template <typename> class k { +public: + using as = i::as; + h::c operator[](long l) { + k<int[]>::as d = 0; + return d[l]; + } +}; +class : public k<int[]> { } a; +long c, f; +void m() +{ + for (long b; b <= 6; b++) + for (long g; g < b; g++) { + unsigned long e = g; + c = 0; + for (; c < b; c++) + f = e >>= 1; + a[g] = f; + } +}