This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/49491] New: Superflouos move because of unnecessary spill for 2-operand insn.
- From: "gjl at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 21 Jun 2011 17:25:15 +0000
- Subject: [Bug middle-end/49491] New: Superflouos move because of unnecessary spill for 2-operand insn.
- Auto-submitted: auto-generated
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: unassigned@gcc.gnu.org
ReportedBy: gjl@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