------- Comment #6 from matz at gcc dot gnu dot org  2009-04-29 00:17 -------
Andrew is right.  There is no "known" alignment (or misalignment) as far
as the gimple code is concerned, only the natural alignment:

send_probe (struct outdata * outdata, struct timeval * tp)
{
  struct timeval * D.1240;
  D.1240_2 = &outdata_1(D)->tv;
  memcpy (D.1240_2, tp_3(D), 8); [tail call]
  return;
}

Here D.1240_2 is of type "struct timeval *", hence has natural alignment
of 8 byte, so the expansion of memcpy is completely correct to assume the
alignment.

The bug is the type of D.1240.  It needs to be an unaligned version of the
above, but I don't think we have such pointer types.

It worked before expand from SSA simply by accident, because TER would
have folded the component_ref into the memcpy call, so the expander could
see what this really is about.  Had there been two such memcpy calls TER
wouldn't have done that and the same problem would have happened.

The user should have the possibility to announce the unalignedness to the
compiler via casts, like so:

  memcpy((char*)&outdata->tv, tp, sizeof outdata->tv);

(or void* or whatever).  This doesn't work currently, as the emitted gimple
code loses that cast.

So, there're two things: explicit alignment changing casts are lost and
the type of ADDR_EXPR of non-naturally aligned fields has the wrong pointer
type (losing the unalignedness).

The former problem is a bit problematic to solve, as parameter passing
always has an implicit conversion to the formal parameter type (void* in this
case).  We don't want to lose alignment info just because of that conversion,
only for explicit ones.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39954

Reply via email to