re PR target/91102 (aarch64 ICE on Linux kernel with -Os starting with r270266)
authorVladimir Makarov <vmakarov@redhat.com>
Wed, 10 Jul 2019 16:07:10 +0000 (16:07 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Wed, 10 Jul 2019 16:07:10 +0000 (16:07 +0000)
2019-07-10  Vladimir Makarov  <vmakarov@redhat.com>

PR target/91102
* lra-constraints.c (process_alt_operands): Don't match user
defined regs only if they are early clobbers.

2019-07-10  Vladimir Makarov  <vmakarov@redhat.com>

PR target/91102
* gcc.target/aarch64/pr91102.c: New test.

From-SVN: r273357

gcc/ChangeLog
gcc/lra-constraints.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/pr91102.c [new file with mode: 0644]

index f109a8cc5eff90560313e98cf8db8f0bc9cbdb4c..e7004e3b95c0e6ab04b4bf7e02fab373c2166142 100644 (file)
@@ -1,3 +1,9 @@
+2019-07-10  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR target/91102
+       * lra-constraints.c (process_alt_operands): Don't match user
+       defined regs only if they are early clobbers.
+
 2019-07-10  Marc Glisse  <marc.glisse@inria.fr>
 
        * wide-int.h (wi::lshift): Reject negative values for the fast path.
index d1d99e01cde01cdd0ebad1efa810cc5c260de221..55d8d133d3941bbf7cca478ad28c5dc6f9d6e658 100644 (file)
@@ -2172,8 +2172,9 @@ process_alt_operands (int only_alternative)
                    else
                      {
                        /* Operands don't match.  If the operands are
-                          different user defined explicit hard registers,
-                          then we cannot make them match.  */
+                          different user defined explicit hard
+                          registers, then we cannot make them match
+                          when one is early clobber operand.  */
                        if ((REG_P (*curr_id->operand_loc[nop])
                             || SUBREG_P (*curr_id->operand_loc[nop]))
                            && (REG_P (*curr_id->operand_loc[m])
@@ -2192,9 +2193,17 @@ process_alt_operands (int only_alternative)
                                && REG_P (m_reg)
                                && HARD_REGISTER_P (m_reg)
                                && REG_USERVAR_P (m_reg))
-                             break;
+                             {
+                               int i;
+                               
+                               for (i = 0; i < early_clobbered_regs_num; i++)
+                                 if (m == early_clobbered_nops[i])
+                                   break;
+                               if (i < early_clobbered_regs_num
+                                   || early_clobber_p)
+                                 break;
+                             }
                          }
-
                        /* Both operands must allow a reload register,
                           otherwise we cannot make them match.  */
                        if (curr_alt[m] == NO_REGS)
index e531f0a3b97215ace403dbdc20367d0dd65ecaac..6b2bf884bfdb4a0e58ecdb59738f88035f6f3e2e 100644 (file)
@@ -1,3 +1,8 @@
+2019-07-10  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR target/91102
+       * gcc.target/aarch64/pr91102.c: New test.
+
 2019-07-10  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/91126
diff --git a/gcc/testsuite/gcc.target/aarch64/pr91102.c b/gcc/testsuite/gcc.target/aarch64/pr91102.c
new file mode 100644 (file)
index 0000000..70b9904
--- /dev/null
@@ -0,0 +1,26 @@
+/* PR target/91102 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (long d, long l)
+{
+  register long e asm ("x1") = d;
+  register long f asm("x2") = l;
+  asm ("" : : "r" (e), "r" (f));
+  return 3;
+}
+
+struct T { int i; int j; };
+union S { long h; struct T t; };
+
+void
+bar (union S b)
+{
+  while (1)
+    {
+      union S c = b;
+      c.t.j++;
+      b.h = foo (b.h, c.h);
+    }
+}