http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15087
Richard Guenther <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|WAITING |SUSPENDED --- Comment #7 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-01-10 15:29:09 UTC --- (In reply to comment #3) > Subject: Re: New: IA64: Wrong alignment for structure > > 8 byte > > hjl at lucon dot org wrote: > > IA64 softwae runtime convention document, section 3.3.1 says that > > object greater that 8 bytes whould be aligned at 16 byte boundary. But > > gcc doesn't do it. > > This is a known problem, except it is much more complicated than what HJ > has stated. You really have to look at the documentation here to > properly understand what is going on. > > The Software Conventions and Runtime Architecure (SCRA), section 3.3.1 > Global Variables, says that dynamically allocated regions (e.g. malloc), > and external data items greater than 8 bytes must be aligned to 16-byte > boundaries. It also says that smaller objects must have alignment of > the nearest power of 2 equal to or larger than their size. So a global > structure object of 3 chars must have an alignment of 4. And the global > structure object in HJ's example must have an alignment of 16. > > The SCRA also says, in section 4.2 Aggregate Types, that an aggregate > type has the same alignment as the most strictly aligned field. There > is an example showing a 24-byte structure type which has 8-byte > alignment. A structure type of 3 bytes has alignment of 1, and the > structure type in HJ's example has alignment 8. > > So the tricky part here is that if an aggregate object is local, then > its alignment is only guaranteed to be as large as the alignment of its > most strictly aligned field. However, if an aggregate object is global > (extern), then its alignment is a power of 2 equal to or larger than its > size up to 16. This is an unusual convention I have never seen before, > and gcc currently has no support for it. I looked at this once a few > years ago and didn't see any easy way to implement it. I think we have > to add a new hook to implement it, and I never got around to that. > > Just assuming the larger alignment for an aggregate object is not safe. > If we have a local object in one module, take its address, and then > pass the address to another module, then we might segfault if we > dereference it assuming it has the larger alignment. So this means we > must assume objects have the smaller alignment when dereferencing > pointers to them, and we must assume they have the larger alignment when > creating them. > > We can do better if we had a reliable way to know if we were accessing a > local or global object. I am not sure if we have this info. Things are > probably easier now than when I first looked, what with cgraph, > functions-as-trees, and tree-ssa. In the simple case, if we are > directly accessing a decl, and the decl is global, then we should be > able to assume the larger alignment. This basically means that layout_type has to assume the object is local (thus, TYPE_ALIGN is the conservative low value - this value is also used when accessign the object via a pointer). layout_decl on the other hand does have the information whether the object is local or global and can properly specify DECL_ALIGN to be higher. > Gcc is currently self-consistent. The problem only arises when linking > gcc compiled code with icc compiled code, as icc implements the ABI as > specified. > > Fixing gcc means introducing a minor ABI change, which makes this more > complicated. Once we start increasing alignment for global objects, we > can't immediately assume such larger alignments when derefencing them, > as that fails if linked with code compiled by an older gcc version. If > we just continue assuming the smaller alignments on dereference for a > gcc version or two, then we can spread the ABI breakage over a few > years, and it will be less likely to affect anyone. So we fix the > alignments in version X, and then wait until version X+2 before using > the new alignments for optimization purposes. This means versions X-1 > and X+2 will be incompatible, but presumably few people would try > cross-linking code compiled by two gcc versions which are 4 versions apart. So, I am suspending this bug since the architecture in question lingers in a semi-dead state and thus any ABI breakage is probably unwanted.