re PR rtl-optimization/79728 (ICE in setup_pressure_classes, at ira.c:912)
authorBernd Schmidt <bernds@redhat.com>
Tue, 14 Mar 2017 17:50:46 +0000 (11:50 -0600)
committerJeff Law <law@gcc.gnu.org>
Tue, 14 Mar 2017 17:50:46 +0000 (11:50 -0600)
PR rtl-optimization/79728
* regs.h (struct target_regs): New field
x_contains_allocatable_regs_of_mode.
(contains_allocatable_regs_of_mode): New macro.
* reginfo.c (init_reg_sets_1): Initialize it, and change
contains_reg_of_mode so it includes global regs as well.
* reload.c (push_reload): Use contains_allocatable_regs_of_mode
rather than contains_regs_of_mode.

PR rtl-optimization/79728
* gcc.target/i386/sse-globalreg.c: New test.

From-SVN: r246138

gcc/ChangeLog
gcc/reginfo.c
gcc/regs.h
gcc/reload.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/sse-globalreg.c [new file with mode: 0644]

index 29987fe..c6f0dd5 100644 (file)
@@ -1,3 +1,14 @@
+2017-03-14  Bernd Schmidt  <bschmidt@redhat.com>
+
+       PR rtl-optimization/79728
+       * regs.h (struct target_regs): New field
+       x_contains_allocatable_regs_of_mode.
+       (contains_allocatable_regs_of_mode): New macro.
+       * reginfo.c (init_reg_sets_1): Initialize it, and change
+       contains_reg_of_mode so it includes global regs as well.
+       * reload.c (push_reload): Use contains_allocatable_regs_of_mode
+       rather than contains_regs_of_mode.
+
 2017-03-14  Martin Liska  <mliska@suse.cz>
 
        * doc/invoke.texi: Document options that can't be combined with
index a2e0b68..a7df02d 100644 (file)
@@ -468,19 +468,29 @@ init_reg_sets_1 (void)
   memset (contains_reg_of_mode, 0, sizeof (contains_reg_of_mode));
   for (m = 0; m < (unsigned int) MAX_MACHINE_MODE; m++)
     {
-      HARD_REG_SET ok_regs;
+      HARD_REG_SET ok_regs, ok_regs2;
       CLEAR_HARD_REG_SET (ok_regs);
+      CLEAR_HARD_REG_SET (ok_regs2);
       for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
-       if (!fixed_regs [j] && HARD_REGNO_MODE_OK (j, (machine_mode) m))
-         SET_HARD_REG_BIT (ok_regs, j);
+       if (!TEST_HARD_REG_BIT (fixed_nonglobal_reg_set, j)
+           && HARD_REGNO_MODE_OK (j, (machine_mode) m))
+         {
+           SET_HARD_REG_BIT (ok_regs, j);
+           if (!fixed_regs[j])
+             SET_HARD_REG_BIT (ok_regs2, j);
+         }
 
       for (i = 0; i < N_REG_CLASSES; i++)
        if ((targetm.class_max_nregs ((reg_class_t) i, (machine_mode) m)
             <= reg_class_size[i])
            && hard_reg_set_intersect_p (ok_regs, reg_class_contents[i]))
          {
-            contains_reg_of_mode [i][m] = 1;
-            have_regs_of_mode [m] = 1;
+            contains_reg_of_mode[i][m] = 1;
+            if (hard_reg_set_intersect_p (ok_regs2, reg_class_contents[i]))
+              {
+                have_regs_of_mode[m] = 1;
+                contains_allocatable_reg_of_mode[i][m] = 1;
+              }
          }
      }
 }
index 09c8da4..bdaa9ba 100644 (file)
@@ -218,6 +218,10 @@ struct target_regs {
   /* 1 if the corresponding class contains a register of the given mode.  */
   char x_contains_reg_of_mode[N_REG_CLASSES][MAX_MACHINE_MODE];
 
+  /* 1 if the corresponding class contains a register of the given mode
+     which is not global and can therefore be allocated.  */
+  char x_contains_allocatable_reg_of_mode[N_REG_CLASSES][MAX_MACHINE_MODE];
+
   /* Record for each mode whether we can move a register directly to or
      from an object of that mode in memory.  If we can't, we won't try
      to use that mode directly when accessing a field of that mode.  */
@@ -243,6 +247,8 @@ extern struct target_regs *this_target_regs;
   (this_target_regs->x_have_regs_of_mode)
 #define contains_reg_of_mode \
   (this_target_regs->x_contains_reg_of_mode)
+#define contains_allocatable_reg_of_mode \
+  (this_target_regs->x_contains_allocatable_reg_of_mode)
 #define direct_load \
   (this_target_regs->x_direct_load)
 #define direct_store \
index 9d27a7c..598b78d 100644 (file)
@@ -1055,7 +1055,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 #ifdef CANNOT_CHANGE_MODE_CLASS
       && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, rclass)
 #endif
-      && contains_reg_of_mode[(int) rclass][(int) GET_MODE (SUBREG_REG (in))]
+      && contains_allocatable_reg_of_mode[rclass][GET_MODE (SUBREG_REG (in))]
       && (CONSTANT_P (SUBREG_REG (in))
          || GET_CODE (SUBREG_REG (in)) == PLUS
          || strict_low
@@ -1164,7 +1164,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 #ifdef CANNOT_CHANGE_MODE_CLASS
       && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)), outmode, rclass)
 #endif
-      && contains_reg_of_mode[(int) rclass][(int) GET_MODE (SUBREG_REG (out))]
+      && contains_allocatable_reg_of_mode[rclass][GET_MODE (SUBREG_REG (out))]
       && (CONSTANT_P (SUBREG_REG (out))
          || strict_low
          || (((REG_P (SUBREG_REG (out))
index eec5c79..8e7a1dd 100644 (file)
@@ -1,3 +1,8 @@
+2017-03-14  Bernd Schmidt  <bschmidt@redhat.com>
+
+       PR rtl-optimization/79728
+       * gcc.target/i386/sse-globalreg.c: New test.
+
 2017-03-14  Martin Liska  <mliska@suse.cz>
 
        PR lto/66295
diff --git a/gcc/testsuite/gcc.target/i386/sse-globalreg.c b/gcc/testsuite/gcc.target/i386/sse-globalreg.c
new file mode 100644 (file)
index 0000000..818a2b6
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -w" } */
+/* { dg-require-effective-target sse2 } */
+
+register int a __asm__("xmm0");
+void fn1() {}