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);
+}

Reply via email to