[Bug target/69051] New: Misaligned read from the stack when using odd sized character array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69051 Bug ID: 69051 Summary: Misaligned read from the stack when using odd sized character array Product: gcc Version: 5.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: m.frohiky at gmail dot com Target Milestone: --- This simple code: void filler(unsigned char *blk); long f(void) { unsigned char blk[65]; filler(blk); return ((unsigned long)blk[0] << 24) | ((unsigned long)blk[1] << 16) | ((unsigned long)blk[2] << 8) | ((unsigned long)blk[3] << 0); } compiled with any kind of optimization: m68k-linux-gnu-gcc -S p.c -O2 generates assembly code that can not be executed due to the misaligned read from the stack: f2: link.w %fp,#-68 pea -65(%fp) jsr filler move.l -65(%fp),%d0# this line fails unlk %fp rts move.l fails because -65(%fp) is an odd address. One possible workaround is to mark used elements as modified by inline assembly: addr = ((unsigned long)blk[0] << 24); asm("" : "=m"(blk[0])); addr |= ((unsigned long)blk[1] << 16); asm("" : "=m"(blk[1])); addr |= ((unsigned long)blk[2] << 8); asm("" : "=m"(blk[2])); addr |= ((unsigned long)blk[3] << 0); The compiler is installed from Debian repository.
[Bug target/69051] Misaligned read from the stack when using odd sized character array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69051 --- Comment #2 from ⎓ --- After the move.l line, address error exception is executed. And that is expected as that line tries to access 32 bit word from an odd address.
[Bug target/69051] Misaligned read from the stack when using odd sized character array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69051 --- Comment #4 from ⎓ --- Whoops! I didn't expect that because I was relying on the -m68000 flag. Then I'll have to try with that compiler. Maybe there should be a warning for using an unsupported CPU architecture?
[Bug rtl-optimization/99847] New: Optimization breaks alignment on CPU32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99847 Bug ID: 99847 Summary: Optimization breaks alignment on CPU32 Product: gcc Version: 10.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: m.frohiky at gmail dot com Target Milestone: --- For CPU32 architecture optimizes two byte accesses into a single word access, without any regard that the original array may be unaligned. So this code: void ntoh(const uint8_t *idata, uint16_t *odata) { *odata = ((uint16_t)idata[0] << 8) | idata[1]; } Compiled with -Os or -O2 produces: move.l 4(%sp),%a1 move.l 8(%sp),%a0 move.w (%a1),(%a0) rts And if idata (address in register a1) is not aligned, the CPU will crash. The compiler I'm using is m68k-linux-gnu-gcc (g++ has the same problem) which comes from Debian repository. The exact version is "(Debian 10.2.1-6) 10.2.1 20210110" Even if it's relying on exception handler to handle the unaligned data it makes no sense because it's sooo much slower.
[Bug target/99847] Optimization breaks alignment on CPU32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99847 --- Comment #2 from ⎓ --- The same thing is with other way around. I.e.: void ntoh(uint16_t idata, uint8_t *odata) { odata[0] = idata >> 8; odata[1] = idata & 0xff; } results with: move.l 8(%sp),%a0 move.w 6(%sp),(%a0) rts I've tried with both -mstrict-align and -mno-strict-align and there are no differences in the produced assembly file (generated with -S).
[Bug target/99847] Optimization breaks alignment on CPU32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99847 --- Comment #4 from ⎓ --- Hmm... I was hoping to get away with the readily available compiler, and I thought that it's actually used for CPU32. Ok, I'll try then with a specific one tomorrow. But still, ABI can't request that all bytes in a uint8_t array are aligned. I mean, you can never expect uint8_t pointer to be aligned, regardless of the used ABI. On the other hand, according to Wiki: > The 68020 had no alignment restrictions on data access. So that could explain it. If it really is the wrong compiler kind, then I've gotta admit, this is the second time something like that happened to me because of my laziness to build a compiler. Shouldn't the old and new m68k be separated or something, so a problem like this can't happen? Maybe another issue for that?
[Bug target/99847] Optimization breaks alignment on CPU32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99847 ⎓ changed: What|Removed |Added Status|WAITING |RESOLVED Resolution|--- |INVALID --- Comment #5 from ⎓ --- I can confirm that everything works as it should with m68k-unknown-elf-gcc/g++ build with crosstool-NG. But I would still prefer that m68k-linux-* refuses to work with the older CPUs or something like that. This problem could potentially discourage less experienced people away from experimenting with m68k.