question about attribute aligned for functions

Martin Sebor msebor@gmail.com
Thu Nov 29 18:29:00 GMT 2018


On 11/28/18 9:07 PM, Jeff Law wrote:
> On 11/27/18 11:57 AM, Martin Sebor wrote:
>> On 11/26/18 3:37 PM, Jeff Law wrote:
>>> On 11/23/18 12:31 PM, Martin Sebor wrote:
>>>> GCC currently accepts the declaration of f0 below but ignores
>>>> the attribute.  On aarch64 (and I presume on other targets with
>>>> a default function alignment greater than 1), GCC rejects f1
>>>> with an error, even though it accepts -falign-functions=1
>>>> without as much as a warning.
>>>>
>>>> Clang, on the other hand, rejects f0 with a hard error because
>>>> the alignment is not a power of two, but accepts f1 and appears
>>>> to honor the attribute.  It also accepts -falign-functions=1.
>>>>
>>>> I think diagnosing f0 with a warning is helpful because an explicit
>>>> zero alignment is most likely a mistake (especially when it comes
>>>> from a macro or some computation).
>>>>
>>>> But I don't see a good reason to reject a program that specifies
>>>> a smaller alignment for a function when the default (or minimum)
>>>> alignment is greater.  A smaller alignment is trivially satisfied
>>>> by a greater alignment so either accepting it or dropping it seems
>>>> preferable to failing with an error (either could be with or without
>>>> a warning).
>>>>
>>>>     __attribute__ ((aligned (0))) void f0 (void);   // accepted, ignored
>>>>     __attribute__ ((aligned (1))) void f1 (void);   // aarch64 error
>>>>     __attribute__ ((aligned (4))) void f4 (void);   // okay
>>>>
>>>> Does anyone know why GCC rejects the program, or can anyone think
>>>> of a reason why GCC should not behave as suggested above?
>>> Note we have targets that support single byte opcodes and do not have
>>> any requirements for functions starting on any boundary.  mn103 comes to
>>> mind.
>>>
>>> However, the attribute can't be used to decrease a function's alignment,
>>> so values of 0 or 1 are in practice totally uninteresting and one could
>>> make an argument to warn for them.
>>
>> The attribute does reduce the default alignment at least on some
>> targets.  For instance, on x86_64 it lowers it from the default
>> 16 to as little as 2, but it silently ignores 1.
> [ ... ]
> You cannot use this attribute to decrease the alignment of a function,
> only to increase it.  However, when you explicitly specify a function
> alignment this overrides the effect of the
> @option{-falign-functions} (@pxref{Optimize Options}) option for this
> function.
> [ ... ]
> 
> My reading of that would be that I would get an error/warning if I even
> specified an alignment attribute which decreased the alignment.
> 
> If it instead said something like
> 
> You can not rely on this attribute to decrease ...
> 
> Then current behavior (where apparently you can decrease the alignment
> on some ports) makes much more sense.
> 
> I guess it ultimately depends on how one interprets that tidbit from the
> docs.

GCC does disallow decreasing the function alignment -- but only
for functions that were already declared with a more restrictive
one.  Like this:

   __attribute__ ((aligned (4))) void f (void);

   __attribute__ ((aligned (2))) void f (void);

   warning: ignoring attribute ‘aligned (2)’ because it conflicts with 
attribute ‘aligned (4)’

It doesn't warn about going from the default (say 16 on i86)
to something smaller, and it honors that lower alignment up
to the supported minimum.  It's probably worth clarifying in
the manual.  Let me propose something.

>>>
>>> Whether or not to warn in general if the alignment attribute is smaller
>>> than the default may be subject to debate.  I guess it depends on the
>>> general intent that we'd find in real world codes.
>>
>> I would expect real world code to care about achieving at least
>> the specified alignment.
> If we only allow increasing, yes.  At which point what do the values 0
> or 1 realistically mean?

If we only allowed increasing then both 0 and 1 would be
meaningless.

> 
> If we allow decreasing, then the user may be asking for a smaller
> alignment to achieve better code density.

Yes, that's definitely possible (I just opened pr88231 -
aligned functions laid down inefficiently, as I noticed this
doesn't work as well as it could and arguably should).  But they
can't get it if the target doesn't support it.  In which case I
think adding a new warning to point it out might be useful.  At
the same time, users wanting maximum density across all their
targets shouldn't have to worry about what the minimum alignment
is on each of them and hardwire different constants into
the attribute.  I think they should be able to specify 1 and
have GCC round it up as necessary, with no warning.  So I'd make
the new warning off by default.

>> A less restrictive alignment requirement is satisfied by providing
>> a more restrictive one, and (the above notwithstanding) the manual
>> documents that
>>
>>    You cannot use this attribute to decrease the alignment of
>>    a function, only to increase it.
>>
>> So I wouldn't expect real code to be relying on decreasing
>> the alignment.
>>
>> That said, since GCC does make it possible to decrease the default
>> alignment of functions, I can think of no reason for it not to
>> continue when it's possible.  I.e., on targets with underaligned
>> instruction reads to be honor requests for underaligned functions.
>> On strictly aligned targets I think the safe thing to do is to
>> quietly ignore requests for smaller alignments by default, and
>> perhaps provide a new option to request a warning (with the warning
>> being disabled by default).
>>
>> Do you see a problem with this approach?
> ISTM we need to figure out whether or not we consider an attempt to
> lower the alignment as invalid vs we'll try, but no guarantees.

Agreed.  Let me know if the approach above makes sense to you.
I can look into adding the new warning either next or in stage
1 if it's too late now.

Martin



More information about the Gcc mailing list