http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53942
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-07-16
11:31:59 UTC ---
C testcase for just -O2 -m32 -mtune=pentium2:
struct S
{
unsigned short data[3];
unsigned int x;
unsigned int y;
};
struct S *baz (void);
__attribute__ ((noinline))
static unsigned char
foo (struct S *x, unsigned char y)
{
unsigned char c = 0;
unsigned char v = x->data[0];
c |= v;
v = ((x->data[1]) & (1 << y)) ? 1 : 0;
c |= v << 1;
v = ((x->data[2]) & 0xff) & (1 << y);
c |= v << 2;
return c;
}
void
bar (void)
{
struct S *s = baz ();
s->x = foo (s, 6);
s->y = foo (s, 7);
}
cant_combine_insn_p already handles hard regs likely spilled correctly if they
are just seen in a simple register move, unfortunately in this case there is no
simple reg move, but instead a zero extension already in the *.expand dump:
(insn 4 3 5 2 (set (reg:SI 80 [ ISRA.4 ])
(zero_extend:SI (reg:HI 2 cx [ ISRA.4 ]))) pr53942.c:12 -1
(nil))
I wonder if either we shouldn't force the HI cx register first into pseudo and
have separate zero extension afterwards (the other alternative would be if we
have a zero or sign extension from hard register likely spilled, force the hard
register into a pseudo in the combiner at the spot where it used to be zero
extended).