Unaligned memory access in -O3 only

153 Views Asked by At

I'm using GCC as compiler and my target is a Cortex-R52 (armv8-r) core.

Being char *str, I have the following piece of code

*++str = '0';

When I compile it using -O2 or -Os , gcc is generating the following assembly code:

movs    r3,#0x30
strb    r0,[r1,#0x2]
strb    r3,[r1,#0x1]

which executes well. However, if I use -O3 instead, gcc generates the following:

movs    r3,#0x30
strh    r3,[r1,#0x1]

which causes a data abort exception, with DFSR = 0x0000_0A21 (Data Fault Status), which translates to Alignment Fault, Abort caused by a write instruction and DFAR is valid. In both cases, r1 = 0x2000_0910, and in the second scenario I can see DFAR = 0x2000_0911.

As far as I can tell, the difference between strb and strh is that the first stores a byte (8 bits) and the second stores a halfword (16 bits). I've tried modifying r1 so it holds 0x2000_0911 in the second scenario, and the issue does not happen. I am guessing that having a half word access in a memory address that is not 2-byte aligned gives you an error.

Would this be correct? If so, why is gcc creating this assembly and what options I have to fix it?

Note: I'm using other flags as well, but since they are all the same for both scenarios I don't know whether it's relevant.

Edit #1

  • The issue is gone after adding -mno-unaligned-access flag (thanks to @Eugene Sh. for the tip). Now -O3 flag generates the same x2 strb instructions as the -O2 flag. The question I would have now is: was the problem not including this flag, or is there something else wrong?
  • Size of '0' is 4 bytes (and size of char is 1 byte). stackoverflow.com/questions/2172943/size-of-character-a-in-c-c. Not sure what this means though, since as mentioned in the comments the compiler is generating a 2-byte access.
  • The exact compiler I'm using is NXP GCC for Arm Embedded Processors v10.2 build 1728; Version: 1728; Build id: 202307190908. So not a standard gcc compiler
  • I would need some time to create a standalone version of the issue, and I'm not sure whether it's worth it as my issue is now gone. In case it helps, the full list of compiler flags I'm using is: -mcpu=cortex-r52 -mthumb -mlittle-endian -mfloat-abi=hard -mfpu=neon-fp-armv8 -mtp=soft -ffreestanding -fno-common -fdata-sections -ffunction-sections -fno-builtin -Wl,--build-id=none -std=c17 -O3
0

There are 0 best solutions below