https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70729
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2016-04-19 Ever confirmed|0 |1 --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- So the argument is that C1[S_n+1] doesn't alias in[] because of the omp simd pragma and its guarantees? Otherwise I don't see how that can be guaranteed. loop->safelen is 2147483647 it seems that INT_MAX is a special value (of course loops could iterate more than INT_MAX times, so that special value is badly choosen - better use some negative value like -1 as special value). And invariant motion could use that property but does not. Index: gcc/tree-ssa-loop-im.c =================================================================== --- gcc/tree-ssa-loop-im.c (revision 235201) +++ gcc/tree-ssa-loop-im.c (working copy) @@ -2198,6 +2198,9 @@ ref_indep_loop_p (struct loop *loop, im_ { gcc_checking_assert (MEM_ANALYZABLE (ref)); + if (loop->safelen == INT_MAX) + return true; + return ref_indep_loop_p_2 (loop, ref, false); } fixes this. But better abstract loop->safelen == INT_MAX into a predicate in cfgloop.h. But even with that the loop is not vectorized because of t.C:66:25: note: def_stmt: prephitmp_56 = PHI <_5(4), _20(6)> t.C:66:25: note: type of def: unknown t.C:66:25: note: Unsupported pattern. t.C:66:25: note: not vectorized: unsupported use in stmt. t.C:66:25: note: unexpected pattern. because even if LIM manages to hoist this PRE has messed up this before and we end up with <bb 2>: _5 = this_4(D)->S_n; if (_5 > 0) goto <bb 4>; else goto <bb 3>; <bb 3>: return; <bb 4>: pretmp_54 = this_4(D)->C2; pretmp_57 = this_4(D)->C1; pretmp_60 = MEM[(int * *)this_4(D) + 56B]; _20 = this_4(D)->S_n; <bb 5>: # i_33 = PHI <0(4), i_28(6)> # prephitmp_56 = PHI <_5(4), _20(6)> notice the redundant this->S_n load.