[Bug rtl-optimization/49807] New: Missed byte (subreg) extraction
gjl at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Jul 21 19:32:00 GMT 2011
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49807
Summary: Missed byte (subreg) extraction
Product: gcc
Version: 4.6.1
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: rtl-optimization
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: gjl@gcc.gnu.org
Target: avr
This C source:
#define SPDR (*((char volatile*) 0x2c))
void read_adc (long big)
{
SPDR = big >> 24;
SPDR = big >> 16;
SPDR = big >> 8;
SPDR = big;
}
compiles with
avr-gcc -S -Os -dp -mmcu=atmega8
to:
read_adc:
movw r26,r24 ; 2 *movsi/1 [length = 2]
movw r24,r22
mov r20,r27 ; 28 *ashrsi3_const/3 [length = 6]
clr r23
sbrc r20,7
com r23
mov r21,r23
mov r22,r23
out 44-0x20,r20 ; 9 *movqi/3 [length = 1]
movw r20,r26 ; 29 *ashrsi3_const/3 [length = 5]
clr r23
sbrc r21,7
com r23
mov r22,r23
out 44-0x20,r20 ; 13 *movqi/3 [length = 1]
mov r20,r25 ; 30 *ashrsi3_const/3 [length = 6]
mov r21,r26
mov r22,r27
clr r23
sbrc r22,7
dec r23
out 44-0x20,r20 ; 17 *movqi/3 [length = 1]
out 44-0x20,r24 ; 20 *movqi/3 [length = 1]
ret ; 26 return [length = 1]
The shifts are done explicitely where the bytes could be saved directly.
Combiner tries insns like
Failed to match this instruction:
(set (mem/v:QI (const_int 44))
(subreg:QI (reg:SI 49) 1))
But they don't match because of MEM_VOLATILE_P so that the MEM
does not match memory_operand as obviously volatile_ok is 0 at that moment.
Must the backend split such insns by hand?
Changing the source like
#define SPDR0 (*((char*) 0x2c))
#define SPDR1 (*((char*) 0x2d))
#define SPDR2 (*((char*) 0x2e))
#define SPDR3 (*((char*) 0x2f))
void read_adc (long big)
{
SPDR0 = big >> 24;
SPDR1 = big >> 16;
SPDR2 = big >> 8;
SPDR3 = big;
}
and it compiles fine:
read_adc:
out 44-0x20,r25 ; 8 *movqi/3 [length = 1]
out 45-0x20,r24 ; 11 *movqi/3 [length = 1]
out 46-0x20,r23 ; 14 *movqi/3 [length = 1]
out 47-0x20,r22 ; 16 *movqi/3 [length = 1]
ret ; 26 return [length = 1]
== configure ==
Target: avr
Configured with: ../../gcc.gnu.org/gcc-4_6-branch/configure --target=avr
--prefix=/local/gnu/install/gcc-4.6-mingw32 --host=i586-mingw32
--build=i686-linux-gnu --enable-languages=c,c++ --disable-nls --disable-shared
--with-dwarf2
Thread model: single
gcc version 4.6.1 20110620 (prerelease) (GCC)
More information about the Gcc-bugs
mailing list