------- 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