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.

Reply via email to