Groups | Search | Server Info | Login | Register


Groups > comp.arch.embedded > #32478

Re: arm-gcc, Cortex-M0+, uint64_t and alignment

From pozz <pozzugno@gmail.com>
Newsgroups comp.arch.embedded
Subject Re: arm-gcc, Cortex-M0+, uint64_t and alignment
Date 2026-01-21 17:57 +0100
Organization A noiseless patient Spider
Message-ID <10kr0gf$29a7t$1@dont-email.me> (permalink)
References (4 earlier) <10koet6$1dlne$2@dont-email.me> <10kq1m7$1un41$1@dont-email.me> <10kq4mi$1vcdq$1@dont-email.me> <10kqpg9$26oa0$1@dont-email.me> <10kqu02$280ts$1@dont-email.me>

Show all headers | View raw


Il 21/01/2026 17:13, David Brown ha scritto:
> On 21/01/2026 15:58, pozz wrote:
>> Il 21/01/2026 10:02, David Brown ha scritto:
>>> On 21/01/2026 09:11, pozz wrote:
>>>> Il 20/01/2026 18:44, David Brown ha scritto:
>>>>> On 20/01/2026 18:09, pozz wrote:
>>>>>> Il 20/01/2026 17:41, Grant Edwards ha scritto:
>>>>>>> On 2026-01-20, David Brown <david.brown@hesbynett.no> wrote:
>>>>>>>
>>>>>>>> You can't reduce the alignment of a struct or its elements by 
>>>>>>>> adding an
>>>>>>>> __aligned_ attribute to the struct itself or any of its fields.  
>>>>>>>> The
>>>>>>>> best you can do on the struct itself is __attribute__((packed)). 
>>>>>>>> But
>>>>>>>> that can come with disadvantages, and inefficient use.
>>>>>>>
>>>>>>> Yep making a structure aligned is an excellent way to introduce 
>>>>>>> subtle
>>>>>>> bugs that happen when somebody, somewhere passes a pointer to one of
>>>>>>> those structure fields to some library function. 
>>>>>>
>>>>>> However, as long as the application runs on Cortex-M0+, the 
>>>>>> aligned version shouldn't introduce issues, should it?
>>>>>>
>>>>>>
>>>>>
>>>>> Correctly aligned data is never a problem.  /Misaligned/ data is a 
>>>>> problem.
>>>>>
>>>>> The Cortex-M0+ cannot access misaligned data directly.  But if the 
>>>>> compiler knows that it is misaligned - by "packed" struct, or 
>>>>> "aligned" attribute on the typedef - it should break apart the 
>>>>> accesses into bytes or 16-bit half-words as necessary.  (Aligning a 
>>>>> uint64_t to 4 byte alignment will not be a problem.)
>>>>
>>>> However for Cortex-M0+ uint64_t aligned at 4 bytes is:
>>>> - aligned for the core (two 4-bytes aligned accesses are required)
>>>
>>> Yes.  As far as I know, the M0+ core does not need any alignment 
>>> greater than 4 for any purpose.  (But I might not know everything 
>>> about the core!)  There can be alignment requirements for other 
>>> things, such as DMA.
>>>
>>>> - misaligned for the ABI and the compiler
>>>
>>> Yes.
>>>
>>>>
>>>> We agree that forcing the gcc compiler to consider 4-bytes as the 
>>>> required alignment of uint64_t (using aligned attribute) is always 
>>>> safe. 
>>>
>>> No.
>>>
>>> It will almost always be safe, but you don't have any guarantees.  
>>> The compiler knows that if "p" is of type "uint64_t *", then 
>>> "(uintptr_t) p & 0x07" will always be zero.  Is it likely that you 
>>> would have anything in your code where that is relevant, and also 
>>> that the compiler would generate code that relies on that 
>>> assumption?  No, it is very unlikely.
>>>
>>> But there is a general principle that you should not lie to your 
>>> compiler - don't write code that executes UB, breaks ABIs, or is 
>>> otherwise breaking the contract you have with the compiler unless you 
>>> are using compiler features that let you keep everything honest.
>>>
>>> Part of that is that code you are writing now for the M0+ might be 
>>> copied or adapted to a different target at a different time.  Maybe 
>>> on a different core, the same data will be read using some kind of 
>>> SIMD or vector instruction that /does/ require 8-byte alignment.  
>>> Don't mess these things without telling your compiler.  And don't 
>>> mess with them without telling future maintainers and programmers 
>>> using the code (including your future self).
>>
>> But it is exactly what I wanted to do: explictly tell the compiler to 
>> align uint64_t at a 4-bytes address (as I wrote, with attribute 
>> align). I didn't think to lie my best friend compiler.
>>
> 
> uint64_t on 32-bit EABI ARM has an alignment of 8 bytes.  That's cut in 
> stone, and you cannot change it (short of adding a new ABI to the 
> toolchain).  If you try to use uint64_t objects that are not 8-byte 
> aligned, or try to use pointers that are not 8-byte aligned to access 
> uint64_t types, you are lying to your compiler.
> 
> If you make a new type that is like a uint64_t but with an "aligned(4)" 
> attribute, you have a /new/ type.  And that type will work just like you 
> want - it is an 8 byte unsigned integer with a 4 byte alignment.  As 
> long as you use that consistently, you'll be fine.
> 
>> What I wanted to know is if there were other issues or drawback, such 
>> as more instructions penalty. 
> 
> The drawback from trying to use an object of a type with an improper 
> alignment is that you have UB.  What more reasons do you want for not 
> doing it?

Most probably I can't explain what I want to say. I don't want to use an 
*improper* alignment (different from the one that gcc really is using). 
I want to know what happens when I *instruct* the compiler to use a 
4-bytes alignment for uint64_t in the context of Cortex-M0+ core only.

In other words, is it completely safe to use, as you suggested,

    typedef uint64_t __attribute__((align(4))) uint64_a;

???

 From what you wrote, I think yes. Maybe just a very small optimization 
penalty.


>> From the goldbot link that you share in another post, it seems there's 
>> a penalty of a single instruction (it's strange, it seems the compiler 
>> needs to save the struct pointer to r3, before loading the two halves 
>> of the word, but only if uint64_t is aligned to 4-bytes).
>>
> 
> The compiler is not perfect here - there is definitely an extra 
> instruction because it is reading the low word first.  (clang reads the 
> low word first for uint64_t as well, meaning it gives worse code for A 
> and B as well.)  In real code, rather than a brief test snippet, other 
> factors could mean this does not happen - it's only because the pointer 
> happens to be in r0 that you see it here.
> 
> But there's no harm in filing a gcc bug on this, looking for an obvious 
> improvement.
> 
>>
>>> I would be extremely surprised to find code that fails to work on an 
>>> M0+ because of a uint64_t pointer that is 4-byte aligned but not 
>>> 8-byte aligned.  But if /I/ want to use 64-bit integers with 4-byte 
>>> alignments, I'd use the typedef'd aligned type for the object type 
>>> and for any relevant pointers.
>>
>> Yes, of course. Even if I don't understand why the compiler isn't able 
>> to align at 4-bytes address the uint64_t member in struct B.
>>
> 
> It can't align the uint64_t member because the EABI says uint64_t (or, 
> rather, unsigned long long) is 8 bytes aligned.  gcc didn't make those 
> rules - ARM did.

But struct B is defined with correct alignment attribute for uint64_t 
member. I tried also:

struct B {
     uint32_t x;
     uint64_t y __attribute__((aligned(4)));
};

The struct size is always 16, so y is placed at offset 8 and not 4. It 
seems to me gcc isn't able to respect the aligned attribute of 4 bytes 
when it is specified inside the struct definition.

I don't see many differences with:

typedef __attribute__((aligned(4))) uint64_t uint64_a;

struct C {
     uint32_t x;
     uint64_a y;
};

> 
> As I briefly mentioned before, there are a number of very poor choices 
> in the EABI (and the 32-bit ARM ABI used for Linux).  This is far from 
> the worst.
> 
>>>> However, what really changes in the binary output?
>>>>
>>>> In some cases, the address of uint64_t can change from 8-bytes to 
>>>> 4-bytes aligned address (because we instructed it to do so). What 
>>>> about the code that accesses uint64_t aligned to 4-bytes? Is it 
>>>> identical between 4- and 8-bytes alignment requirement? I think so, 
>>>> because in both case, the compiler should add two load/store 4-bytes 
>>>> instructions.
>>>>
>>>
>>
> 

Back to comp.arch.embedded | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

arm-gcc, Cortex-M0+, uint64_t and alignment pozz <pozzugno@gmail.com> - 2026-01-20 13:26 +0100
  Re: arm-gcc, Cortex-M0+, uint64_t and alignment David Brown <david.brown@hesbynett.no> - 2026-01-20 17:07 +0100
    Re: arm-gcc, Cortex-M0+, uint64_t and alignment Grant Edwards <invalid@invalid.invalid> - 2026-01-20 16:41 +0000
      Re: arm-gcc, Cortex-M0+, uint64_t and alignment pozz <pozzugno@gmail.com> - 2026-01-20 18:09 +0100
        Re: arm-gcc, Cortex-M0+, uint64_t and alignment David Brown <david.brown@hesbynett.no> - 2026-01-20 18:44 +0100
          Re: arm-gcc, Cortex-M0+, uint64_t and alignment pozz <pozzugno@gmail.com> - 2026-01-21 09:11 +0100
            Re: arm-gcc, Cortex-M0+, uint64_t and alignment David Brown <david.brown@hesbynett.no> - 2026-01-21 10:02 +0100
              Re: arm-gcc, Cortex-M0+, uint64_t and alignment pozz <pozzugno@gmail.com> - 2026-01-21 15:58 +0100
                Re: arm-gcc, Cortex-M0+, uint64_t and alignment David Brown <david.brown@hesbynett.no> - 2026-01-21 17:13 +0100
                Re: arm-gcc, Cortex-M0+, uint64_t and alignment pozz <pozzugno@gmail.com> - 2026-01-21 17:57 +0100
                Re: arm-gcc, Cortex-M0+, uint64_t and alignment David Brown <david.brown@hesbynett.no> - 2026-01-22 10:03 +0100
        Re: arm-gcc, Cortex-M0+, uint64_t and alignment Grant Edwards <invalid@invalid.invalid> - 2026-01-20 17:48 +0000
      Re: arm-gcc, Cortex-M0+, uint64_t and alignment David Brown <david.brown@hesbynett.no> - 2026-01-20 18:41 +0100
        Re: arm-gcc, Cortex-M0+, uint64_t and alignment Grant Edwards <invalid@invalid.invalid> - 2026-01-20 18:10 +0000
          Re: arm-gcc, Cortex-M0+, uint64_t and alignment David Brown <david.brown@hesbynett.no> - 2026-01-20 22:32 +0100
            Re: arm-gcc, Cortex-M0+, uint64_t and alignment Grant Edwards <invalid@invalid.invalid> - 2026-01-21 03:38 +0000
              Re: arm-gcc, Cortex-M0+, uint64_t and alignment David Brown <david.brown@hesbynett.no> - 2026-01-21 08:54 +0100
    Re: arm-gcc, Cortex-M0+, uint64_t and alignment pozz <pozzugno@gmail.com> - 2026-01-20 17:55 +0100
      Re: arm-gcc, Cortex-M0+, uint64_t and alignment David Brown <david.brown@hesbynett.no> - 2026-01-20 22:24 +0100

csiph-web