https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65317
Bug ID: 65317 Summary: [SH] Shifts used instead of and with const_int 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*-*-* int test_01 (int a, int b) { int r = a < 0; return r << 31; } compiled with -O2 -m4: shll r4 movt r0 and #1,r0 rts rotr r0 could be: mov.l .Lconst,r0 rts and r4,r0 .Lconst: .long 0x80000000 combine says: Failed to match this instruction: (set (reg:SI 168 [ D.1470 ]) (and:SI (reg:SI 4 r4 [ a ]) (const_int -2147483648 [0xffffffff80000000]))) Notice that this int test_02 (int a) { return a & 0x80000000; } compiles as expected: mov.l .L18,r0 rts and r4,r0 .L19: .align 2 .L18: .long -2147483648 If code size is important, or constant loads should be avoided (because it's not shared etc), a shorter (in code size) version would be: shll r4 movt r0 rts rotr r0 Another case: int foo3(int *x) { int i,y; int a[40]; int b[40] __attribute__ ((aligned(32))); int c[40] __attribute__ ((aligned(128))); for (i = 0; i < 40; i++) a[i] = *x++; for (i = 0; i < 40; i++) b[i] = *x++; for (i = 0; i < 40; i++) c[i] = *x++; y = -99; for (i = 0; i < 40; i++) y = y + a[i] + b[i] + c[i]; return y; } compiles to: mov.l r14,@-r15 mov #-5,r3 add #-80,r15 mov.w .L11,r2 add #-80,r15 add r15,r2 mov r15,r14 mov r2,r15 mov r15,r7 add #31,r7 mov #5,r1 shld r3,r7 <<<< shld r1,r7 <<<< mov #0,r0 mov #40,r1 .align 2 .L2: mov.l @(r0,r4),r2 .... The shifts used to mask out lower bits can be replaced with a much simpler and with a constant. Combine says: Failed to match this instruction: (set (reg/f:SI 217) (and:SI (reg/f:SI 214) (const_int -32 [0xffffffffffffffe0]))) It seems that it's better to allow any constant for the *andsi_compact pattern and split out the constant load if it doesn't fit into K08. An and with constant 0x80000000 could be treated as a special case to emit the shorter sequence: shll r4 movt r0 rts rotr r0 If constant calculation optimization is done (PR 65069), it would automatically be converted to: mov #1,r0 rotr r0 rts and r4,r0 which is equivalent and maybe even better because the input is not mutated.