http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49491
Summary: Superflouos move because of unnecessary spill for 2-operand insn. Product: gcc Version: 4.7.0 Status: UNCONFIRMED Keywords: missed-optimization, ra Severity: normal Priority: P3 Component: middle-end AssignedTo: unassig...@gcc.gnu.org ReportedBy: g...@gcc.gnu.org Target: avr This is an optimization flaw I observe in current 4.7 trunk (r175201) and also in upcoming 4.6.1. This is the C source: unsigned int shift1 (unsigned char x, unsigned char y) { return (x|y) >> 3; } The machine (AVR) just has 2-operand instructions. It occurs for AVR but presumably is not target-specific and so I chose "middle-end" as component because reload generates insn 27. Function shift1 gets x in r24, y in r22 and has to return the result in r24 (LSB) and r25 (MSB). The code produced is: shift1: or r22,r24 ; 7 iorqi3/1 [length = 1] mov r24,r22 ; 27 *movqi/1 [length = 1] lsr r24 ; 24 *lshrqi3/5 [length = 3] lsr r24 lsr r24 ldi r25,lo8(0) ; 25 *movqi/1 [length = 1] ret ; 30 return [length = 1] Instead of a simple or r24,r22 there is or r22,r24 mov r24,r22 There is nothing I can see in avr BE that forces this move; iorqi3 insn is commutative and no insn involved needs an (early) clobber. Without the shift, code is as expected: unsigned int or1 (unsigned char x, unsigned char y) { return x|y; } or1: or r24,r22 ; 23 iorqi3/1 [length = 1] ldi r25,lo8(0) ; 24 *movqi/1 [length = 1] ret ; 28 return [length = 1] =================== Command line: avr-gcc shr.c -Os -dp -S -v =================== Using built-in specs. COLLECT_GCC=avr-gcc COLLECT_LTO_WRAPPER=/local/gnu/install/gcc-4.7/libexec/gcc/avr/4.7.0/lto-wrapper Target: avr Configured with: ../../gcc.gnu.org/trunk/configure --target=avr --prefix=/local/gnu/install/gcc-4.7 --disable-nls --disable-shared --enable-languages=c,c++ --with-dwarf2 Thread model: single gcc version 4.7.0 20110620 (experimental) (GCC) COLLECT_GCC_OPTIONS='-Os' '-dp' '-S' '-v' /local/gnu/install/gcc-4.7/libexec/gcc/avr/4.7.0/cc1 -quiet -v shr.c -quiet -dumpbase shr.c -dp -auxbase shr -Os -version -o shr.s GNU C (GCC) version 4.7.0 20110620 (experimental) (avr) compiled by GNU C version 4.3.2 [gcc-4_3-branch revision 141291], GMP version 5.0.1, MPFR version 3.0.0-p8, MPC version 0.8.2 GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096