https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65266
Bug ID: 65266 Summary: [SH] Use rotcl for bit reversals Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: olegendo at gcc dot gnu.org Target: sh*-*-* The following examples are small bit reversals: unsigned int test1 (unsigned int a) { return ((a & 1) << 1) | ((a >> 1) & 1); } unsigned int test2 (unsigned int a) { return ((a & 1) << 2) | (((a >> 1) & 1) << 1) | ((a >> 2) & 1); } unsigned int test3 (unsigned int a) { return ((a & 1) << 3) | (((a >> 1) & 1) << 2) | (((a >> 2) & 1) << 1) | (((a >> 3) & 1) << 0); } where test3 currently compiles to: mov r4,r0 mov #1,r2 tst #8,r0 and r4,r2 movt r1 mov r2,r0 shll2 r0 tst r1,r1 mov r0,r1 mov r4,r0 and #2,r0 rotcl r1 add r0,r0 mov r0,r2 mov r4,r0 or r1,r2 tst #4,r0 mov #-1,r1 mov r2,r0 negc r1,r1 add r1,r1 rts or r1,r0 where a minimal sequence would be: shlr r4 movt r0 shlr r4 rotcl r0 shlr r4 rotcl r0 shlr r4 rotcl r0 For example, combine tries the following pattern: Failed to match this instruction: (set (reg:SI 186 [ D.2006 ]) (ior:SI (ior:SI (and:SI (ashift:SI (reg/v:SI 176 [ a ]) (const_int 1 [0x1])) (const_int 4 [0x4])) (zero_extract:SI (reg/v:SI 176 [ a ]) (const_int 1 [0x1]) (const_int 3 [0x3]))) (and:SI (ashift:SI (reg/v:SI 176 [ a ]) (const_int 3 [0x3])) (const_int 8 [0x8])))) A predicate that accepts IOR chains of single bit selections (via zero_extract or shift-and) could be used to capture the sequence during combine and then smash it in split1. Possibly related: PR 65265, PR 63321.