]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/59133 (ICE after r204219 on SPEC2006 435.gromacs.)
authorVladimir Makarov <vmakarov@redhat.com>
Wed, 20 Nov 2013 20:32:57 +0000 (20:32 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Wed, 20 Nov 2013 20:32:57 +0000 (20:32 +0000)
2013-11-20  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/59133
* lra.c (expand_reg_data): Add new argument.  Set up ALL_REGS for
new pseudos.
(lra_create_new_reg_with_unique_value): Pass new argument value.
(lra_emit_add, lra_emit_move): Ditto.
* lra-constraints.c (in_class_p): Add check for move for a new
insn.
(change_class): Rename to lra_change_class.  Move to lra-int.h.
(get_reload_reg, narrow_reload_pseudo_class): Adjust calls of
change_class.
(process_addr_reg, process_addr): Ditto.
(curr_insn_transform): Ditto.  Add check on old pseudo for
optional reload.
* lra-int.h (lra_get_regno_hard_regno): Move below.
(lra_change_class): Renamed change_class from lra.c.

2013-11-20  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/59133
* gcc.target/i386/pr59133.c: New.

From-SVN: r205141

gcc/ChangeLog
gcc/lra-constraints.c
gcc/lra-int.h
gcc/lra.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr59133.c [new file with mode: 0644]

index 810670e2d987f6f1fbd8169edacf64056c4a7686..19ba024b7116460a932167db9a66bf25d59c88c4 100644 (file)
@@ -1,3 +1,21 @@
+2013-11-20  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/59133
+       * lra.c (expand_reg_data): Add new argument.  Set up ALL_REGS for
+       new pseudos.
+       (lra_create_new_reg_with_unique_value): Pass new argument value.
+       (lra_emit_add, lra_emit_move): Ditto.
+       * lra-constraints.c (in_class_p): Add check for move for a new
+       insn.
+       (change_class): Rename to lra_change_class.  Move to lra-int.h.
+       (get_reload_reg, narrow_reload_pseudo_class): Adjust calls of
+       change_class.
+       (process_addr_reg, process_addr): Ditto.
+       (curr_insn_transform): Ditto.  Add check on old pseudo for
+       optional reload.
+       * lra-int.h (lra_get_regno_hard_regno): Move below.
+       (lra_change_class): Renamed change_class from lra.c.
+
 2013-11-20  David Malcolm  <dmalcolm@redhat.com>
 
        * gdbhooks.py (VecPrinter.children): Don't attempt to iterate
index 94b6e2559ef4453be720b8fceb6fafc3ddf4245a..4c88cca669d28e2ef48b767eae88489acaa7539e 100644 (file)
@@ -269,7 +269,11 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class)
         typically moves that have many alternatives, and restricting
         reload pseudos for one alternative may lead to situations
         where other reload pseudos are no longer allocatable.  */
-      || INSN_UID (curr_insn) >= new_insn_uid_start)
+      || (INSN_UID (curr_insn) >= new_insn_uid_start
+         && curr_insn_set != NULL
+         && (OBJECT_P (SET_SRC (curr_insn_set))
+             || (GET_CODE (SET_SRC (curr_insn_set)) == SUBREG
+                 && OBJECT_P (SUBREG_REG (SET_SRC (curr_insn_set)))))))
     /* When we don't know what class will be used finally for reload
        pseudos, we use ALL_REGS.  */
     return ((regno >= new_regno_start && rclass == ALL_REGS)
@@ -381,21 +385,6 @@ init_curr_insn_input_reloads (void)
   curr_insn_input_reloads_num = 0;
 }
 
-/* Change class of pseudo REGNO to NEW_CLASS.  Print info about it
-   using TITLE.         Output a new line if NL_P.  */
-static void
-change_class (int regno, enum reg_class new_class,
-             const char *title, bool nl_p)
-{
-  lra_assert (regno >= FIRST_PSEUDO_REGISTER);
-  if (lra_dump_file != NULL)
-    fprintf (lra_dump_file, "%s to class %s for r%d",
-            title, reg_class_names[new_class], regno);
-  setup_reg_classes (regno, new_class, NO_REGS, new_class);
-  if (lra_dump_file != NULL && nl_p)
-    fprintf (lra_dump_file, "\n");
-}
-
 /* Create a new pseudo using MODE, RCLASS, ORIGINAL or reuse already
    created input reload pseudo (only if TYPE is not OP_OUT).  The
    result pseudo is returned through RESULT_REG.  Return TRUE if we
@@ -442,7 +431,7 @@ get_reload_reg (enum op_type type, enum machine_mode mode, rtx original,
              dump_value_slim (lra_dump_file, original, 1);
            }
          if (new_class != lra_get_allocno_class (regno))
-           change_class (regno, new_class, ", change", false);
+           lra_change_class (regno, new_class, ", change to", false);
          if (lra_dump_file != NULL)
            fprintf (lra_dump_file, "\n");
          return false;
@@ -667,7 +656,7 @@ narrow_reload_pseudo_class (rtx reg, enum reg_class cl)
   if (! REG_P (reg) || (int) REGNO (reg) < new_regno_start)
     return;
   if (in_class_p (reg, cl, &rclass) && rclass != cl)
-    change_class (REGNO (reg), rclass, "      Change", true);
+    lra_change_class (REGNO (reg), rclass, "      Change to", true);
 }
 
 /* Generate reloads for matching OUT and INS (array of input operand
@@ -1133,7 +1122,7 @@ process_addr_reg (rtx *loc, rtx *before, rtx *after, enum reg_class cl)
        }
       else if (new_class != NO_REGS && rclass != new_class)
        {
-         change_class (regno, new_class, "        Change", true);
+         lra_change_class (regno, new_class, "    Change to", true);
          return false;
        }
       else
@@ -2796,7 +2785,7 @@ process_address (int nop, rtx *before, rtx *after)
              regno = REGNO (*ad.base_term);
              if (regno >= FIRST_PSEUDO_REGISTER
                  && cl != lra_get_allocno_class (regno))
-               change_class (regno, cl, "      Change", true);
+               lra_change_class (regno, cl, "      Change to", true);
              new_reg = SET_SRC (set);
              delete_insns_since (PREV_INSN (last_insn));
            }
@@ -3316,7 +3305,7 @@ curr_insn_transform (void)
            if (new_class != NO_REGS && get_reg_class (regno) != new_class)
              {
                lra_assert (ok_p);
-               change_class (regno, new_class, "      Change", true);
+               lra_change_class (regno, new_class, "      Change to", true);
              }
          }
       }
@@ -3395,7 +3384,7 @@ curr_insn_transform (void)
              && lra_former_scratch_operand_p (curr_insn, i))
            {
              int regno = REGNO (op);
-             change_class (regno, NO_REGS, "      Change", true);
+             lra_change_class (regno, NO_REGS, "      Change to", true);
              if (lra_get_regno_hard_regno (regno) >= 0)
                /* We don't have to mark all insn affected by the
                   spilled pseudo as there is only one such insn, the
@@ -3410,6 +3399,7 @@ curr_insn_transform (void)
              && lra_undo_inheritance_iter < LRA_MAX_INHERITANCE_PASSES
              && goal_alt[i] != NO_REGS && REG_P (op)
              && (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER
+             && regno < new_regno_start
              && ! lra_former_scratch_p (regno)
              && reg_renumber[regno] < 0
              && (curr_insn_set == NULL_RTX
index cb45c65d13af6b6fa141f2a408dd2b374c09e4b6..c545d9d354f98345d59fb9298247c9b1dd8f5932 100644 (file)
@@ -33,16 +33,6 @@ along with GCC; see the file COPYING3.       If not see
    base and index registers might require a reload too.         */
 #define LRA_MAX_INSN_RELOADS (MAX_RECOG_OPERANDS * 3)
 
-/* Return the hard register which given pseudo REGNO assigned to.
-   Negative value means that the register got memory or we don't know
-   allocation yet.  */
-static inline int
-lra_get_regno_hard_regno (int regno)
-{
-  resize_reg_info ();
-  return reg_renumber[regno];
-}
-
 typedef struct lra_live_range *lra_live_range_t;
 
 /* The structure describes program points where a given pseudo lives.
@@ -394,6 +384,31 @@ extern void lra_eliminate_reg_if_possible (rtx *);
 
 \f
 
+/* Return the hard register which given pseudo REGNO assigned to.
+   Negative value means that the register got memory or we don't know
+   allocation yet.  */
+static inline int
+lra_get_regno_hard_regno (int regno)
+{
+  resize_reg_info ();
+  return reg_renumber[regno];
+}
+
+/* Change class of pseudo REGNO to NEW_CLASS.  Print info about it
+   using TITLE.  Output a new line if NL_P.  */
+static void inline
+lra_change_class (int regno, enum reg_class new_class,
+                 const char *title, bool nl_p)
+{
+  lra_assert (regno >= FIRST_PSEUDO_REGISTER);
+  if (lra_dump_file != NULL)
+    fprintf (lra_dump_file, "%s class %s for r%d",
+            title, reg_class_names[new_class], regno);
+  setup_reg_classes (regno, new_class, NO_REGS, new_class);
+  if (lra_dump_file != NULL && nl_p)
+    fprintf (lra_dump_file, "\n");
+}
+
 /* Update insn operands which are duplication of NOP operand.  The
    insn is represented by its LRA internal representation ID.  */
 static inline void
index ff89342d0c321e81684e9ee5bfd33b1788522a91..f4791a2de8befcffc1b7e8717b6b2552c8ca4a87 100644 (file)
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -130,11 +130,13 @@ static void invalidate_insn_data_regno_info (lra_insn_recog_data_t, rtx, int);
 
 /* Expand all regno related info needed for LRA.  */
 static void
-expand_reg_data (void)
+expand_reg_data (int old)
 {
   resize_reg_info ();
   expand_reg_info ();
   ira_expand_reg_equiv ();
+  for (int i = (int) max_reg_num () - 1; i >= old; i--)
+    lra_change_class (i, ALL_REGS, "      Set", true);
 }
 
 /* Create and return a new reg of ORIGINAL mode.  If ORIGINAL is NULL
@@ -178,7 +180,7 @@ lra_create_new_reg_with_unique_value (enum machine_mode md_mode, rtx original,
                 title, REGNO (new_reg));
       fprintf (lra_dump_file, "\n");
     }
-  expand_reg_data ();
+  expand_reg_data (max_reg_num ());
   setup_reg_classes (REGNO (new_reg), rclass, NO_REGS, rclass);
   return new_reg;
 }
@@ -417,7 +419,7 @@ lra_emit_add (rtx x, rtx y, rtx z)
   /* Functions emit_... can create pseudos -- so expand the pseudo
      data.  */
   if (old != max_reg_num ())
-    expand_reg_data ();
+    expand_reg_data (old);
 }
 
 /* The number of emitted reload insns so far.  */
@@ -443,7 +445,7 @@ lra_emit_move (rtx x, rtx y)
       /* Function emit_move can create pseudos -- so expand the pseudo
         data.  */
       if (old != max_reg_num ())
-       expand_reg_data ();
+       expand_reg_data (old);
       return;
     }
   lra_emit_add (x, XEXP (y, 0), XEXP (y, 1));
index a172098f56686b497ae92d1248421bc51aa3c5e8..348a0ce7320cd5d0b219180221ba05f1d1838f97 100644 (file)
@@ -1,3 +1,8 @@
+2013-11-20  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/59133
+       * gcc.target/i386/pr59133.c: New.
+
 2013-11-20  Joseph Myers  <joseph@codesourcery.com>
 
        PR middle-end/21718
diff --git a/gcc/testsuite/gcc.target/i386/pr59133.c b/gcc/testsuite/gcc.target/i386/pr59133.c
new file mode 100644 (file)
index 0000000..ef8ef74
--- /dev/null
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -ffast-math -march=core-avx2" } */
+
+#define XX 0
+#define YY 1
+#define ZZ 2
+#define DIM 3
+typedef float matrix[DIM][DIM];
+typedef float rvec[DIM];
+extern int det (matrix);
+extern void foo(matrix);
+
+void bar1 (int n,int *index,rvec x[],matrix trans)
+{
+  float   xt,yt,zt;
+  int    i,ii;
+  
+  for(i=0; (i<n); i++) {
+    ii=index ? index[i] : i;
+    xt=x[ii][XX];
+    yt=x[ii][YY];
+    zt=x[ii][ZZ];
+    x[ii][XX]=trans[XX][XX]*xt+trans[XX][YY]*yt+trans[XX][ZZ]*zt;
+    x[ii][YY]=trans[YY][XX]*xt+trans[YY][YY]*yt+trans[YY][ZZ]*zt;
+    x[ii][ZZ]=trans[ZZ][XX]*xt+trans[ZZ][YY]*yt+trans[ZZ][ZZ]*zt;
+  }
+}
+
+
+void bar2 (int n, rvec x[]) 
+{
+  int     m;
+  matrix  trans;
+  
+  foo (trans);
+  
+  if (det (trans) < 0) {
+    for(m=0; (m<DIM); m++)
+      trans[ZZ][m] = -trans[ZZ][m];
+  }  
+  bar1 (n,(int*) 0,x,trans);
+}