https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106635
Richard Earnshaw <rearnsha at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |INVALID Status|WAITING |RESOLVED --- Comment #5 from Richard Earnshaw <rearnsha at gcc dot gnu.org> --- Your original code contains (after stripping out the volatile): u32 temp_32 = (u32)status_data_base_addr; *dst++ = temp_32; data_length++; if(sizeof(addr_t) == 8) { *dst++ = (u32)(((u64)status_data_base_addr)>>32); data_length++; } Which of course on a 64-bit machine simplifies to u32 temp_32 = (u32)status_data_base_addr; *dst++ = temp_32; data_length++; *dst++ = (u32)(((u64)status_data_base_addr)>>32); data_length++; And which the compiler then further simplifies to *([unaligned]u64*)dst = status_data_base_addr; data_length += 2; dst += 2; If the location that dst points to is in normal, cachable, memory, then this will be fine. But if you're writing to non-cachable memory, then you might get a trap. the correct fix is to mark dst as volatile in this case. void CWLCollectReadRegData(volatile u32* dst,u16 reg_start, u32 reg_length,u32* total_length, addr_t status_data_base_addr)