https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63259
--- Comment #7 from thopre01 at gcc dot gnu.org --- (In reply to Oleg Endo from comment #6) > With r218705 on SH (-O2 -m4 -ml) I get the following: > > unsigned short test_099 (unsigned short a, unsigned short b) > { > return (((a & 0xFF00) >> 8) | ((a & 0xFF) << 8)); > } > > compiles to: > extu.w r4,r4 > rts > swap.b r4,r0 This one looks ok except for the zero-extension. Is the swap.b instruction limited to 32 bit values? > > > unsigned short test_08 (unsigned short a, unsigned short b) > { > return b + (((a & 0xFF00) >> 8) | ((a & 0xFF) << 8)); > } > > compiles to: > extu.w r4,r4 > mov r4,r0 > shll8 r4 > shlr8 r0 > or r0,r4 > add r4,r5 > rts > extu.w r5,r0 Strange, could you show the output of -fdump-tree-bswap? > > > Byte swapping of signed short types seems to be not working: > > short test_func_111 (short a, short b, short c) > { > return (((a & 0xFF00) >> 8) | ((a & 0xFF) << 8)); > } > > exts.w r4,r4 > mov r4,r0 > shlr8 r0 > extu.b r0,r0 > shll8 r4 > or r0,r4 > rts > exts.w r4,r0 That's expected. Think about what happens if a = 0x8001. Doing a right shift by 8 bit would give 0xFF80 (due to the most significant bit being 1). The right part of the bitwise OR would give 0x0100 as expected and the result would be 0xFF80, so not a byte swap. It would work with an int though as the highest bit would then be 0, or with unsigned short as a right shift would introduce 0 in the most significant bits. Best regards, Thomas