re PR target/79131 (ICE: in extract_constrain_insn, at recog.c:2213, big-endian ARM)
authorVladimir Makarov <vmakarov@redhat.com>
Fri, 27 Jan 2017 16:50:11 +0000 (16:50 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Fri, 27 Jan 2017 16:50:11 +0000 (16:50 +0000)
2017-01-27  Vladimir Makarov  <vmakarov@redhat.com>

PR target/79131
* lra-assigns.c (find_hard_regno_for_1): Take endianess for into
account to calculate conflict_set.

2017-01-27  Vladimir Makarov  <vmakarov@redhat.com>

PR target/79131
* gcc.target/arm/pr79131.c: Rename to gcc.target/arm/pr79131-1.c.
* gcc.target/arm/pr79131-2.c: New.

From-SVN: r244989

gcc/ChangeLog
gcc/lra-assigns.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr79131-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/pr79131-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/pr79131.c [deleted file]

index b70acef6953e1a8d867a5a949f7bc0bb8a6ac6e4..2c90d06c8d44cc0998eacfe1a983b12e5985ba4c 100644 (file)
@@ -1,3 +1,9 @@
+2017-01-27  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR target/79131
+       * lra-assigns.c (find_hard_regno_for_1): Take endianess for into
+       account to calculate conflict_set.
+
 2017-01-27  Bin Cheng  <bin.cheng@arm.com>
 
        PR rtl-optimization/78559
index 74a3195c4db2a8d18a58fd717e5e742b4daec0f9..0ccd42546b71778db5d9efdd1b6eb7d9e7dcbd5d 100644 (file)
@@ -564,32 +564,45 @@ find_hard_regno_for_1 (int regno, int *cost, int try_only_hard_regno,
   offset = lra_reg_info[regno].offset;
   CLEAR_HARD_REG_SET (impossible_start_hard_regs);
   EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos, conflict_regno)
-    if (lra_reg_val_equal_p (conflict_regno, val, offset))
-      {
-       conflict_hr = live_pseudos_reg_renumber[conflict_regno];
-       nregs = (hard_regno_nregs[conflict_hr]
-                [lra_reg_info[conflict_regno].biggest_mode]);
-       /* Remember about multi-register pseudos.  For example, 2 hard
-          register pseudos can start on the same hard register but can
-          not start on HR and HR+1/HR-1.  */
-       for (hr = conflict_hr + 1;
-            hr < FIRST_PSEUDO_REGISTER && hr < conflict_hr + nregs;
-            hr++)
-         SET_HARD_REG_BIT (impossible_start_hard_regs, hr);
-       for (hr = conflict_hr - 1;
-            hr >= 0 && hr + hard_regno_nregs[hr][biggest_mode] > conflict_hr;
-            hr--)
-         SET_HARD_REG_BIT (impossible_start_hard_regs, hr);
-      }
-    else
-      {
-       add_to_hard_reg_set (&conflict_set,
-                            lra_reg_info[conflict_regno].biggest_mode,
-                            live_pseudos_reg_renumber[conflict_regno]);
-       if (hard_reg_set_subset_p (reg_class_contents[rclass],
-                                  conflict_set))
-         return -1;
-      }
+    {
+      conflict_hr = live_pseudos_reg_renumber[conflict_regno];
+      if (lra_reg_val_equal_p (conflict_regno, val, offset))
+       {
+         conflict_hr = live_pseudos_reg_renumber[conflict_regno];
+         nregs = (hard_regno_nregs[conflict_hr]
+                  [lra_reg_info[conflict_regno].biggest_mode]);
+         /* Remember about multi-register pseudos.  For example, 2
+            hard register pseudos can start on the same hard register
+            but can not start on HR and HR+1/HR-1.  */
+         for (hr = conflict_hr + 1;
+              hr < FIRST_PSEUDO_REGISTER && hr < conflict_hr + nregs;
+              hr++)
+           SET_HARD_REG_BIT (impossible_start_hard_regs, hr);
+         for (hr = conflict_hr - 1;
+              hr >= 0 && hr + hard_regno_nregs[hr][biggest_mode] > conflict_hr;
+              hr--)
+           SET_HARD_REG_BIT (impossible_start_hard_regs, hr);
+       }
+      else
+       {
+         enum machine_mode biggest_conflict_mode
+           = lra_reg_info[conflict_regno].biggest_mode;
+         int biggest_conflict_nregs
+           = hard_regno_nregs[conflict_hr][biggest_conflict_mode];
+         
+         nregs_diff = (biggest_conflict_nregs
+                       - (hard_regno_nregs
+                          [conflict_hr]
+                          [PSEUDO_REGNO_MODE (conflict_regno)]));
+         add_to_hard_reg_set (&conflict_set,
+                              biggest_conflict_mode,
+                              conflict_hr
+                              - (WORDS_BIG_ENDIAN ? nregs_diff : 0));
+         if (hard_reg_set_subset_p (reg_class_contents[rclass],
+                                    conflict_set))
+           return -1;
+       }
+    }
   EXECUTE_IF_SET_IN_SPARSESET (conflict_reload_and_inheritance_pseudos,
                               conflict_regno)
     if (!lra_reg_val_equal_p (conflict_regno, val, offset))
index f326e408743d8812eafd7413c6d5ed2d46b2802b..9b164d304781178d708400cb0cd8c917d370f94c 100644 (file)
@@ -1,3 +1,9 @@
+2017-01-27  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR target/79131
+       * gcc.target/arm/pr79131.c: Rename to gcc.target/arm/pr79131-1.c.
+       * gcc.target/arm/pr79131-2.c: New.
+
 2017-01-27  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        PR target/65484
diff --git a/gcc/testsuite/gcc.target/arm/pr79131-1.c b/gcc/testsuite/gcc.target/arm/pr79131-1.c
new file mode 100644 (file)
index 0000000..3bd9e0f
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbig-endian" } */
+
+long long a;
+enum { NILFS_SEGMENT_USAGE_ACTIVE, NILFS_SEGMENT_USAGE_DIRTY } b;
+void nilfs_sufile_mod_counter(long long p1) {
+  long c = p1;
+  unsigned d = __builtin_bswap64(a);
+  a = __builtin_bswap64(d + c);
+}
+void nilfs_sufile_do_free() {
+  int e, f;
+  e = __builtin_bswap32(b) & 1 << NILFS_SEGMENT_USAGE_DIRTY;
+  f = e;
+  nilfs_sufile_mod_counter(f ? -1 : 0);
+}
diff --git a/gcc/testsuite/gcc.target/arm/pr79131-2.c b/gcc/testsuite/gcc.target/arm/pr79131-2.c
new file mode 100644 (file)
index 0000000..a670f0f
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbig-endian" } */
+
+struct nilfs_segment_usage {
+  int su_flags;
+} a;
+enum { NILFS_SEGMENT_USAGE_ACTIVE, NILFS_SEGMENT_USAGE_DIRTY } fn1();
+int b;
+void fn2(int *, long long);
+void fn3() {
+  int c, d;
+  struct nilfs_segment_usage e = a;
+  fn1();
+  c = e.su_flags & 1 << NILFS_SEGMENT_USAGE_DIRTY;
+  d = c;
+  fn2(&b, d ? -1 : 0);
+}
diff --git a/gcc/testsuite/gcc.target/arm/pr79131.c b/gcc/testsuite/gcc.target/arm/pr79131.c
deleted file mode 100644 (file)
index 3bd9e0f..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -mbig-endian" } */
-
-long long a;
-enum { NILFS_SEGMENT_USAGE_ACTIVE, NILFS_SEGMENT_USAGE_DIRTY } b;
-void nilfs_sufile_mod_counter(long long p1) {
-  long c = p1;
-  unsigned d = __builtin_bswap64(a);
-  a = __builtin_bswap64(d + c);
-}
-void nilfs_sufile_do_free() {
-  int e, f;
-  e = __builtin_bswap32(b) & 1 << NILFS_SEGMENT_USAGE_DIRTY;
-  f = e;
-  nilfs_sufile_mod_counter(f ? -1 : 0);
-}