https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103699
--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> --- (In reply to Petr from comment #6) > For now I have disabled unaligned load/store optimizations in my projects > when dealing with GCC 11 and upwards. As I mentioned you could just add the may_alias attribute and it will work too. You were just lucky that you only ran into this issue for GCC 11 really > I still think that GCC is wrong in this case regardless of strict aliasing. > The code in func_u32() is essentially creating a constant, and GCC 11+ is > the only compiler returning it wrong and also inconsistently between > optimization levels. No you are still violating C/C++ aliasing rules. No matter what you think. It is undefined behavior. Strict aliasing is only enabled for -O2 and above which is why it might look inconsistent. Plus since it is undefined behavior different optimizations level will always have different behavior. Again the following code: uint8_t array[16] {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; writeU64be(array + 6, 0xAABBCCDDEEFF1213); return readU32be(array + 7); Which does basically: uint8_t array[16] {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; *(unsigned long*)(array+6) = __builtin_bswap64(0xAABBCCDDEEFF1213); return *(unsigned*)(array+7); is undefined as you write to array+6 as an unsigned long but then read array+7 as an unsigned type. Plus aligned(1) attribute has nothing to do with the issue here: Take: static unsigned g(unsigned *a) { return *a; } unsigned f(void) { unsigned char array[16] {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; *(unsigned long*)(array) = __builtin_bswap64(0xAABBCCDDEEFF1213); return g((unsigned*)(array)); } ----- CUT --- Compile it with -O2 -fno-early-inlining and you will same bad results as you had got with aligned.