https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63259
--- Comment #10 from thopre01 at gcc dot gnu.org --- (In reply to Oleg Endo from comment #9) > (In reply to thopre01 from comment #7) > > > > Strange, could you show the output of -fdump-tree-bswap? > > Not so strange at all. What is strange is that it should detect such bswap pattern. > After looking at the RTL dumps, I've noticed that > the swap.b insn is generated by the combine pass. I've got a few combine > patterns for matching byte swaps on SH. The pattern for swap.b doesn't > combine well with other ops around/on it. -fdump-tree-bswap says: > > ;; Function test_08 (test_08, funcdef_no=1, decl_uid=1333, cgraph_uid=1, > symbol_order=1) > > test_08 (short unsigned int a, short unsigned int b) > { > short unsigned int _2; > signed short _3; > int _4; > int _5; > signed short _6; > signed short _7; > short unsigned int _8; > short unsigned int _10; > > <bb 2>: > _2 = a_1(D) >> 8; > _3 = (signed short) _2; > _4 = (int) a_1(D); > _5 = _4 << 8; > _6 = (signed short) _5; > _7 = _3 | _6; > _8 = (short unsigned int) _7; > _10 = _8 + b_9(D); > return _10; > > } I have the same gimple and for me the bswap is correctly detected. Can you break at find_bswap_or_nop just after calling find_bswap_or_nop_1 on the if (!source_stmt) and show me the output of p/x n->n ? > > > > > 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. > > As Andreas mentioned, 'a' is promoted to int, so this should be a byte swap. Indeed, my mistake. Ok I tested a bit and found that the problem is the depth at which it's looking. Try to recompile tree-ssa-math-opts.c after increasing the limit number in find_bswap_or_nop. Right now the limit will evaluate to 4 and the gimple I have has a depth of 5.