http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49279
Richard Guenther <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Depends on| |48764 --- Comment #3 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-06-06 13:00:44 UTC --- Indeed PRE thinks that it is loop invariant, presumambly because of TBAA: D.7681_206 = MEM[(const double &)D.7674_199]; D.7680_208 = D.7425_99 * D.7681_206; D.7663_216 = MEM[(const double &)SR.167_105]; D.7664_217 = D.7680_208 + D.7663_216; MEM[(Scalar &)SR.167_105] = D.7664_217; and MEM[(const double &)SR.167_105] is sought to be loop-invariant, not aliasing MEM[(Scalar &)SR.167_105]. We do not see the must-alias because SR.167_105 is value-numbered to some other SSA name and value_dies_in_block_x (after fixing another bug in that function) does not do value-replacement on the stmt it queries stmt_may_clobber_ref_p_1. Then the oracle figures if (!ptr_derefs_may_alias_p (ptr1, ptr2)) return false; and both vars point to restrict tags (but different restrict tags). So this looks to me related to PR48764. Of course this case is somewhat different in that we basically have struct { double * restrict x; } m; double * restrict wrap () { return m.x; } double x; m.x = &x; for (;;) wrap (&x) = wrap (&x) + 1; and GCC thinks that the two restrict qualified pointers point to different things. See the restrict qualified m_data pointer in MapBase. As you are creating a new object via forceAligned -> force_aligned_impl.run -> _convertToForceAligned you effectively are loading from two different restrict qualified pointers. I'll fixup the bug I noticed in value_dies_in_block_x, but it won't fix this PR.