https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115102
Bug ID: 115102 Summary: [SH] GCC misunderstands swap.b instruction Product: gcc Version: 14.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: paul at crapouillou dot net Target Milestone: --- Given the following C code: #include <stdint.h> uint32_t bswap8(uint32_t val) { return (val & 0xffff0000) | ((val & 0xff00) >> 8) | ((val & 0xff) << 8); } GCC will generate (-m4 -Os): _bswap8: mov.l .L2,r1 extu.w r4,r0 swap.b r0,r0 and r1,r4 rts or r4,r0 .L2: .long -65536 GCC understand that it can swap the two lower bytes using the swap.b instruction. However, it seems to believe that it needs to clear up the upper 16 bits first, which is wrong, as those are simply copied over to the destination register. As a result, it will zero-extend to 16 bits first, swap the two low bytes, then apply a high 16-bit mask to the original value, and OR the two results together. This is not optimal, and GCC could simply generate the following: _bswap8: rts swap.b r4,r0