http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51708
Bug #: 51708 Summary: SH Target: SHAD / SHLD constant not CSE-ed Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: target AssignedTo: unassig...@gcc.gnu.org ReportedBy: oleg.e...@t-online.de Target: sh*-*-* If the shift amount is a constant for SHAD / SHLD insns it should be CSE-ed. This could be done in a similar way as in the movnegt insn. Example function: int foo (int* a, int x, int n) { int i; int count; for (i = 0; i < n; i ++) count += (*(a + i) << 12); return count; } compiled with -m4 -O3: cmp/pl r6 bf .L11 shll2 r6 add #-4,r6 shlr2 r6 add #1,r6 .L9: mov.l @r4+,r1 mov #12,r2 ! load constant in loop dt r6 shld r2,r1 ! use constant in loop bf/s .L9 add r1,r0 .L11: rts nop better: cmp/pl r6 bf .L11 shll2 r6 add #-4,r6 shlr2 r6 add #1,r6 mov #12,r2 ! load constant before loop .L9: mov.l @r4+,r1 dt r6 shld r2,r1 ! use constant in loop bf/s .L9 add r1,r0 .L11: rts nop