public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* asking for __attribute__((aligned()) clarification
@ 2019-08-19 12:46 "Markus Fröschle"
  2019-08-19 13:57 ` Paul Koning
  0 siblings, 1 reply; 11+ messages in thread
From: "Markus Fröschle" @ 2019-08-19 12:46 UTC (permalink / raw)
  To: gcc, gnu-gcc-bug

All,

this is my first post on these lists, so please bear with me.

My question is about gcc's __attribute__((aligned()). Please consider the following code:

#include <stdint.h>
    
typedef uint32_t uuint32_t __attribute__((aligned(1)));

uint32_t getuuint32(uint8_t p[]) {
    return *(uuint32_t*)p;
}

This is meant to prevent gcc to produce hard faults/address errors on architectures that do not support unaligned access to shorts/ints (e.g some ARMs, some m68k). On these architectures, gcc is supposed to replace the 32 bit access with a series of 8 or 16 bit accesses.

I originally came from gcc 4.6.4 (yes, pretty old) where this did not work and gcc does not respect the aligned(1) attribute for its code generation (i.e. it generates a 'normal' pointer dereference, consequently crashing when the code executes). To be fair, it is my understanding that the gcc manuals never promised this *would* work.

As - at least as far as I can tell - documentation didn't really change regarding lowering alignment for variables and does not appear to say anything specific regarding pointer dereference on single, misaligned variables, I was pretty astonished to see this working on newer gcc versions (tried 6.2 and 7.4), however. gcc appears to even know the differences within an architecture (68000 generates a bytewise copy while ColdFire - that supports unaligned access - copies a 32 bit value).

My question: is this now intended behaviour we can rely on? If yes, can we have documentation upgraded to clearly state that this use case is valid?

Thank you.
Markus

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: asking for __attribute__((aligned()) clarification
  2019-08-19 12:46 asking for __attribute__((aligned()) clarification "Markus Fröschle"
@ 2019-08-19 13:57 ` Paul Koning
  2019-08-19 14:01   ` Richard Earnshaw (lists)
  0 siblings, 1 reply; 11+ messages in thread
From: Paul Koning @ 2019-08-19 13:57 UTC (permalink / raw)
  To: Markus Fröschle; +Cc: gcc



> On Aug 19, 2019, at 8:46 AM, Markus Fröschle <markus@mubf.de> wrote:
> 
> All,
> 
> this is my first post on these lists, so please bear with me.
> 
> My question is about gcc's __attribute__((aligned()). Please consider the following code:
> 
> #include <stdint.h>
> 
> typedef uint32_t uuint32_t __attribute__((aligned(1)));
> 
> uint32_t getuuint32(uint8_t p[]) {
>    return *(uuint32_t*)p;
> }
> 
> This is meant to prevent gcc to produce hard faults/address errors on architectures that do not support unaligned access to shorts/ints (e.g some ARMs, some m68k). On these architectures, gcc is supposed to replace the 32 bit access with a series of 8 or 16 bit accesses.
> 
> I originally came from gcc 4.6.4 (yes, pretty old) where this did not work and gcc does not respect the aligned(1) attribute for its code generation (i.e. it generates a 'normal' pointer dereference, consequently crashing when the code executes). To be fair, it is my understanding that the gcc manuals never promised this *would* work.

That has never been my understanding.  I've always read the manual to say that "aligned" only INCREASES the alignment.  The normal alignment is that specified by the ABI for the given data type (often, but not always, the size of the primitive type) -- or it is 1 for "packed".

So I use __attribute__ ((packed)) to request byte alignment, and, say, __attribute__ ((packed, aligned(2))) to specify alignment to 2 byte multiples.

	paul


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: asking for __attribute__((aligned()) clarification
  2019-08-19 13:57 ` Paul Koning
@ 2019-08-19 14:01   ` Richard Earnshaw (lists)
  2019-08-19 14:08     ` Alexander Monakov
  0 siblings, 1 reply; 11+ messages in thread
From: Richard Earnshaw (lists) @ 2019-08-19 14:01 UTC (permalink / raw)
  To: Paul Koning, Markus Fröschle; +Cc: gcc

On 19/08/2019 14:57, Paul Koning wrote:
> 
> 
>> On Aug 19, 2019, at 8:46 AM, Markus Fröschle <markus@mubf.de> wrote:
>>
>> All,
>>
>> this is my first post on these lists, so please bear with me.
>>
>> My question is about gcc's __attribute__((aligned()). Please consider the following code:
>>
>> #include <stdint.h>
>>
>> typedef uint32_t uuint32_t __attribute__((aligned(1)));
>>
>> uint32_t getuuint32(uint8_t p[]) {
>>     return *(uuint32_t*)p;
>> }
>>
>> This is meant to prevent gcc to produce hard faults/address errors on architectures that do not support unaligned access to shorts/ints (e.g some ARMs, some m68k). On these architectures, gcc is supposed to replace the 32 bit access with a series of 8 or 16 bit accesses.
>>
>> I originally came from gcc 4.6.4 (yes, pretty old) where this did not work and gcc does not respect the aligned(1) attribute for its code generation (i.e. it generates a 'normal' pointer dereference, consequently crashing when the code executes). To be fair, it is my understanding that the gcc manuals never promised this *would* work.
> 
> That has never been my understanding.  I've always read the manual to say that "aligned" only INCREASES the alignment.  The normal alignment is that specified by the ABI for the given data type (often, but not always, the size of the primitive type) -- or it is 1 for "packed".
> 
> So I use __attribute__ ((packed)) to request byte alignment, and, say, __attribute__ ((packed, aligned(2))) to specify alignment to 2 byte multiples.
> 
> 	paul
> 
> 

Correct, but note that you can only pack structs and unions, not basic 
types.  there is no way of under-aligning a basic type except by 
wrapping it in a struct.

R.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: asking for __attribute__((aligned()) clarification
  2019-08-19 14:01   ` Richard Earnshaw (lists)
@ 2019-08-19 14:08     ` Alexander Monakov
  2019-08-19 14:12       ` Paul Koning
  2019-08-20  5:46       ` Aw: " "Markus Fröschle"
  0 siblings, 2 replies; 11+ messages in thread
From: Alexander Monakov @ 2019-08-19 14:08 UTC (permalink / raw)
  To: Richard Earnshaw (lists); +Cc: Paul Koning, Markus Fröschle, gcc

On Mon, 19 Aug 2019, Richard Earnshaw (lists) wrote:

> Correct, but note that you can only pack structs and unions, not basic types.
> there is no way of under-aligning a basic type except by wrapping it in a
> struct.

I don't think that's true. In GCC-9 the doc for 'aligned' attribute has been
significantly revised, and now ends with

  When used as part of a typedef, the aligned attribute can both increase and
  decrease alignment, and specifying the packed attribute generates a warning. 

(but I'm sure defacto behavior of accepting and honoring reduced alignment on
a typedef'ed scalar type goes way earlier than gcc-9)

Alexander

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: asking for __attribute__((aligned()) clarification
  2019-08-19 14:08     ` Alexander Monakov
@ 2019-08-19 14:12       ` Paul Koning
  2019-08-20  5:46       ` Aw: " "Markus Fröschle"
  1 sibling, 0 replies; 11+ messages in thread
From: Paul Koning @ 2019-08-19 14:12 UTC (permalink / raw)
  To: Alexander Monakov; +Cc: Richard Earnshaw (lists), Markus Fröschle, gcc



> On Aug 19, 2019, at 10:08 AM, Alexander Monakov <amonakov@ispras.ru> wrote:
> 
> On Mon, 19 Aug 2019, Richard Earnshaw (lists) wrote:
> 
>> Correct, but note that you can only pack structs and unions, not basic types.
>> there is no way of under-aligning a basic type except by wrapping it in a
>> struct.
> 
> I don't think that's true. In GCC-9 the doc for 'aligned' attribute has been
> significantly revised, and now ends with
> 
>  When used as part of a typedef, the aligned attribute can both increase and
>  decrease alignment, and specifying the packed attribute generates a warning. 
> 
> (but I'm sure defacto behavior of accepting and honoring reduced alignment on
> a typedef'ed scalar type goes way earlier than gcc-9)

Interesting.  It certainly wasn't that way a decade ago.  And for the old code pattern to generate a warning seems like a bad incompatible change.  Honoring reducing alignments is one thing, complaining about packed is not good.

	paul

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Aw: Re: asking for __attribute__((aligned()) clarification
  2019-08-19 14:08     ` Alexander Monakov
  2019-08-19 14:12       ` Paul Koning
@ 2019-08-20  5:46       ` "Markus Fröschle"
  2019-08-21 14:29         ` Alexander Monakov
  1 sibling, 1 reply; 11+ messages in thread
From: "Markus Fröschle" @ 2019-08-20  5:46 UTC (permalink / raw)
  To: gcc

Thank you (and others) for your answers. Now I'm just as smart as before, however.

Is it a supported, documented, 'long term' feature we can rely on or not?

If yes, I would expect it to be properly documented. If not, never mind.

> Gesendet: Montag, 19. August 2019 um 16:08 Uhr
> Von: "Alexander Monakov" <amonakov@ispras.ru>
> An: "Richard Earnshaw (lists)" <Richard.Earnshaw@arm.com>
> Cc: "Paul Koning" <paulkoning@comcast.net>, "Markus Fröschle" <markus@mubf.de>, gcc@gcc.gnu.org
> Betreff: Re: asking for __attribute__((aligned()) clarification
>
> On Mon, 19 Aug 2019, Richard Earnshaw (lists) wrote:
> 
> > Correct, but note that you can only pack structs and unions, not basic types.
> > there is no way of under-aligning a basic type except by wrapping it in a
> > struct.
> 
> I don't think that's true. In GCC-9 the doc for 'aligned' attribute has been
> significantly revised, and now ends with
> 
>   When used as part of a typedef, the aligned attribute can both increase and
>   decrease alignment, and specifying the packed attribute generates a warning. 
> 
> (but I'm sure defacto behavior of accepting and honoring reduced alignment on
> a typedef'ed scalar type goes way earlier than gcc-9)
> 
> Alexander
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Aw: Re: asking for __attribute__((aligned()) clarification
  2019-08-20  5:46       ` Aw: " "Markus Fröschle"
@ 2019-08-21 14:29         ` Alexander Monakov
  2019-08-21 14:32           ` Paul Koning
  0 siblings, 1 reply; 11+ messages in thread
From: Alexander Monakov @ 2019-08-21 14:29 UTC (permalink / raw)
  To: Markus Fröschle; +Cc: gcc

[-- Attachment #1: Type: text/plain, Size: 860 bytes --]

On Tue, 20 Aug 2019, "Markus Fröschle" wrote:

> Thank you (and others) for your answers. Now I'm just as smart as before, however.
> 
> Is it a supported, documented, 'long term' feature we can rely on or not?
> 
> If yes, I would expect it to be properly documented. If not, never mind.

I think it's properly documented in gcc-9:

  https://gcc.gnu.org/onlinedocs/gcc-9.2.0/gcc/Common-Type-Attributes.html

(the "old" behavior where the compiler would neither honor reduced alignment
nor issue a warning seems questionable, the new documentation promises a more
sensible approach)

In portable code one can also use memcpy to move unaligned data, the compiler
should translate it like an unaligned load/store when size is a suitable
constant:

  int val;
  memcpy(&val, ptr, sizeof val);

(or __builtin_memcpy when -ffreestanding is in effect)

Alexander

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: asking for __attribute__((aligned()) clarification
  2019-08-21 14:29         ` Alexander Monakov
@ 2019-08-21 14:32           ` Paul Koning
  2019-08-21 14:58             ` Alexander Monakov
  0 siblings, 1 reply; 11+ messages in thread
From: Paul Koning @ 2019-08-21 14:32 UTC (permalink / raw)
  To: Alexander Monakov; +Cc: Markus Fröschle, gcc



> On Aug 21, 2019, at 10:28 AM, Alexander Monakov <amonakov@ispras.ru> wrote:
> 
> On Tue, 20 Aug 2019, "Markus Fröschle" wrote:
> 
>> Thank you (and others) for your answers. Now I'm just as smart as before, however.
>> 
>> Is it a supported, documented, 'long term' feature we can rely on or not?
>> 
>> If yes, I would expect it to be properly documented. If not, never mind.
> 
> I think it's properly documented in gcc-9:
> 
>  https://gcc.gnu.org/onlinedocs/gcc-9.2.0/gcc/Common-Type-Attributes.html
> 
> (the "old" behavior where the compiler would neither honor reduced alignment
> nor issue a warning seems questionable, the new documentation promises a more
> sensible approach)

I agree, but if the new approach generates a warning for code that was written to the old rules, that would be unfortunate.

> In portable code one can also use memcpy to move unaligned data, the compiler
> should translate it like an unaligned load/store when size is a suitable
> constant:
> 
>  int val;
>  memcpy(&val, ptr, sizeof val);
> 
> (or __builtin_memcpy when -ffreestanding is in effect)

Yes.  But last I tried, optimizing that for > 1 alignment is problematic because that information often doesn't make it down to the target code even though it is documented to do so.

	paul

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: asking for __attribute__((aligned()) clarification
  2019-08-21 14:32           ` Paul Koning
@ 2019-08-21 14:58             ` Alexander Monakov
  2019-08-21 16:50               ` Paul Koning
  0 siblings, 1 reply; 11+ messages in thread
From: Alexander Monakov @ 2019-08-21 14:58 UTC (permalink / raw)
  To: Paul Koning; +Cc: Markus Fröschle, gcc

On Wed, 21 Aug 2019, Paul Koning wrote:

> I agree, but if the new approach generates a warning for code that was written
> to the old rules, that would be unfortunate.

FWIW I don't know which GCC versions accepted 'packed' on a scalar type.
Already in 2006 GCC 3.4 would issue a warning:

$ echo 'typedef int ui __attribute__((packed));' | gcc34 -xc - -S -o-
        .file   ""
<stdin>:1: warning: `packed' attribute ignored
        .section        .note.GNU-stack,"",@progbits
        .ident  "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-4)"

> Yes.  But last I tried, optimizing that for > 1 alignment is problematic
> because that information often doesn't make it down to the target code even
> though it is documented to do so.

Thanks, indeed this memcpy solution is not so well suited for that.

Alexander

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: asking for __attribute__((aligned()) clarification
  2019-08-21 14:58             ` Alexander Monakov
@ 2019-08-21 16:50               ` Paul Koning
  2019-08-21 17:35                 ` Jonathan Wakely
  0 siblings, 1 reply; 11+ messages in thread
From: Paul Koning @ 2019-08-21 16:50 UTC (permalink / raw)
  To: Alexander Monakov; +Cc: gcc



> On Aug 21, 2019, at 10:57 AM, Alexander Monakov <amonakov@ispras.ru> wrote:
> 
> On Wed, 21 Aug 2019, Paul Koning wrote:
> 
>> I agree, but if the new approach generates a warning for code that was written
>> to the old rules, that would be unfortunate.
> 
> FWIW I don't know which GCC versions accepted 'packed' on a scalar type.

That wasn't what I meant; I was talking about the packed and aligned attributes on struct members.  I thought you were saying that ((packed,aligned(2))) is now a warning.  That doesn't appear to be the case, though; it's accepted without complaint as it always was.

	paul

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: asking for __attribute__((aligned()) clarification
  2019-08-21 16:50               ` Paul Koning
@ 2019-08-21 17:35                 ` Jonathan Wakely
  0 siblings, 0 replies; 11+ messages in thread
From: Jonathan Wakely @ 2019-08-21 17:35 UTC (permalink / raw)
  To: Paul Koning; +Cc: Alexander Monakov, gcc

On Wed, 21 Aug 2019 at 17:50, Paul Koning <paulkoning@comcast.net> wrote:
>
>
>
> > On Aug 21, 2019, at 10:57 AM, Alexander Monakov <amonakov@ispras.ru> wrote:
> >
> > On Wed, 21 Aug 2019, Paul Koning wrote:
> >
> >> I agree, but if the new approach generates a warning for code that was written
> >> to the old rules, that would be unfortunate.
> >
> > FWIW I don't know which GCC versions accepted 'packed' on a scalar type.
>
> That wasn't what I meant; I was talking about the packed and aligned attributes on struct members.  I thought you were saying that ((packed,aligned(2))) is now a warning.  That doesn't appear to be the case, though; it's accepted without complaint as it always was.

Right, nobody's suggesting that should be a warning. The warning is
for trying to pack a scalar variable, which is (and always was)
meaningless.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-08-21 17:35 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-19 12:46 asking for __attribute__((aligned()) clarification "Markus Fröschle"
2019-08-19 13:57 ` Paul Koning
2019-08-19 14:01   ` Richard Earnshaw (lists)
2019-08-19 14:08     ` Alexander Monakov
2019-08-19 14:12       ` Paul Koning
2019-08-20  5:46       ` Aw: " "Markus Fröschle"
2019-08-21 14:29         ` Alexander Monakov
2019-08-21 14:32           ` Paul Koning
2019-08-21 14:58             ` Alexander Monakov
2019-08-21 16:50               ` Paul Koning
2019-08-21 17:35                 ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).