The following patch fixes http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56903
In this test case reload pass gets correct value HARD_REGNO_MODE_OK because it can not create pseudos (can_create_pseudo) and this was actually used that we are in reload (or after reload). LRA can create pseudos therefore it got the wrong answer. The patch fixes it.
OK for the trunk? 2013-04-10 Vladimir Makarov <vmaka...@redhat.com> PR tree-optimization/56903 * config/i386/i386.c (ix86_hard_regno_mode_ok): Add lra_in_progress for return. 2013-04-10 Vladimir Makarov <vmaka...@redhat.com> PR tree-optimization/56903 * gcc.target/i386/pr56903.c: New test.
Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 197679) +++ config/i386/i386.c (working copy) @@ -33976,7 +33976,9 @@ ix86_hard_regno_mode_ok (int regno, enum return true; if (!TARGET_PARTIAL_REG_STALL) return true; - return !can_create_pseudo_p (); + /* LRA can create pseudos but it does not mean that it does not + need to know that the hard register in given mode is OK. */ + return lra_in_progress || !can_create_pseudo_p (); } /* We handle both integer and floats in the general purpose registers. */ else if (VALID_INT_MODE_P (mode)) Index: testsuite/gcc.target/i386/pr56903.c =================================================================== --- testsuite/gcc.target/i386/pr56903.c (revision 0) +++ testsuite/gcc.target/i386/pr56903.c (working copy) @@ -0,0 +1,18 @@ +/* PR rtl-optimization/56903 */ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ +/* { dg-additional-options "-march=pentium3" { target ia32 } } */ + +int a, *b, c; +struct S { int s : 1; } *fn1 (void); +extern int fn3 (void), fn4 (int *); + +void +fn2 (void) +{ + int e = fn3 (); + char f = c + fn1 ()->s * 4; + if (*b && f == e) + a = *b; + fn4 (b); +}