A simple omission...
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2018-11-13 Richard Biener <rguent...@suse.de> PR tree-optimization/87967 * tree-vect-loop.c (vect_transform_loop): Also copy PHIs for constants for the scalar loop. * g++.dg/opt/pr87967.C: New testcase. Index: gcc/tree-vect-loop.c =================================================================== --- gcc/tree-vect-loop.c (revision 266061) +++ gcc/tree-vect-loop.c (working copy) @@ -8264,7 +8257,7 @@ vect_transform_loop (loop_vec_info loop_ e = single_exit (LOOP_VINFO_SCALAR_LOOP (loop_vinfo)); if (! single_pred_p (e->dest)) { - split_loop_exit_edge (e); + split_loop_exit_edge (e, true); if (dump_enabled_p ()) dump_printf (MSG_NOTE, "split exit edge of scalar loop\n"); } Index: gcc/testsuite/g++.dg/opt/pr87967.C =================================================================== --- gcc/testsuite/g++.dg/opt/pr87967.C (nonexistent) +++ gcc/testsuite/g++.dg/opt/pr87967.C (working copy) @@ -0,0 +1,50 @@ +// { dg-do compile } +// { dg-options "-O3" } + +void h(); +template <typename b> struct k { using d = b; }; +template <typename b, template <typename> class> using e = k<b>; +template <typename b, template <typename> class f> +using g = typename e<b, f>::d; +struct l { + template <typename i> using ab = typename i::j; +}; +struct n : l { + using j = g<char *, ab>; +}; +class o { +public: + long r(); +}; +char m; +char s() { + if (m) + return '0'; + return 'A'; +} +class t { +public: + typedef char *ad; + ad m_fn2(); +}; +void fn3() { + char *a; + t b; + bool p = false; + while (*a) { + h(); + o c; + if (*a) + a++; + if (c.r()) { + n::j q; + for (t::ad d = b.m_fn2(), e; d != e; d++) { + char f = *q; + *d = f + s(); + } + p = true; + } + } + if (p) + throw; +}