]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR rtl-optimization/63637 (CSE on x86 asm()-s no longer working due...
authorJakub Jelinek <jakub@redhat.com>
Sun, 1 Feb 2015 17:33:19 +0000 (18:33 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sun, 1 Feb 2015 17:33:19 +0000 (18:33 +0100)
Backported from mainline
2015-01-23  Jakub Jelinek  <jakub@redhat.com>

PR rtl-optimization/63637
PR rtl-optimization/60663
* cse.c (merge_equiv_classes): Set new_elt->cost to MAX_COST
if elt->cost is MAX_COST for ASM_OPERANDS.
(find_sets_in_insn): Fix up comment typo.
(cse_insn): Don't set src_volatile for all non-volatile
ASM_OPERANDS in PARALLELs, but just those with multiple outputs
or with "memory" clobber.  Set elt->cost to MAX_COST
for ASM_OPERANDS in PARALLEL.  Set src_elt->cost to MAX_COST
if new_src is ASM_OPERANDS and elt->cost is MAX_COST.

* gcc.dg/pr63637-1.c: New test.
* gcc.dg/pr63637-2.c: New test.
* gcc.dg/pr63637-3.c: New test.
* gcc.dg/pr63637-4.c: New test.
* gcc.dg/pr63637-5.c: New test.
* gcc.dg/pr63637-6.c: New test.
* gcc.target/i386/pr63637-1.c: New test.
* gcc.target/i386/pr63637-2.c: New test.
* gcc.target/i386/pr63637-3.c: New test.
* gcc.target/i386/pr63637-4.c: New test.
* gcc.target/i386/pr63637-5.c: New test.
* gcc.target/i386/pr63637-6.c: New test.

From-SVN: r220323

15 files changed:
gcc/ChangeLog
gcc/cse.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr63637-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr63637-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr63637-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr63637-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr63637-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr63637-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr63637-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr63637-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr63637-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr63637-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr63637-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr63637-6.c [new file with mode: 0644]

index cb5e9c55ce530078fbf22b313ced2fc2235eacc4..d15282b421f49268a36d95a80f9cacf60fd3b042 100644 (file)
@@ -3,6 +3,17 @@
        Backported from mainline
        2015-01-23  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/63637
+       PR rtl-optimization/60663
+       * cse.c (merge_equiv_classes): Set new_elt->cost to MAX_COST
+       if elt->cost is MAX_COST for ASM_OPERANDS.
+       (find_sets_in_insn): Fix up comment typo.
+       (cse_insn): Don't set src_volatile for all non-volatile
+       ASM_OPERANDS in PARALLELs, but just those with multiple outputs
+       or with "memory" clobber.  Set elt->cost to MAX_COST
+       for ASM_OPERANDS in PARALLEL.  Set src_elt->cost to MAX_COST
+       if new_src is ASM_OPERANDS and elt->cost is MAX_COST.
+
        PR debug/64511
        * dwarf2out.c (struct dw_loc_descr_node): Add chain_next
        GTY markup.
index ec9aff4195ad8df0ea5be8734874477ee6938947..9b8b8160c41dec3c77d95f70f6a1461fabd136e2 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -1805,6 +1805,8 @@ merge_equiv_classes (struct table_elt *class1, struct table_elt *class2)
            }
          new_elt = insert (exp, class1, hash, mode);
          new_elt->in_memory = hash_arg_in_memory;
+         if (GET_CODE (exp) == ASM_OPERANDS && elt->cost == MAX_COST)
+           new_elt->cost = MAX_COST;
        }
     }
 }
@@ -4266,7 +4268,7 @@ find_sets_in_insn (rtx insn, struct set **psets)
     {
       int i, lim = XVECLEN (x, 0);
 
-      /* Go over the epressions of the PARALLEL in forward order, to
+      /* Go over the expressions of the PARALLEL in forward order, to
         put them in the same order in the SETS array.  */
       for (i = 0; i < lim; i++)
        {
@@ -4642,12 +4644,27 @@ cse_insn (rtx insn)
          && REGNO (dest) >= FIRST_PSEUDO_REGISTER)
        sets[i].src_volatile = 1;
 
-      /* Also do not record result of a non-volatile inline asm with
-        more than one result or with clobbers, we do not want CSE to
-        break the inline asm apart.  */
       else if (GET_CODE (src) == ASM_OPERANDS
               && GET_CODE (x) == PARALLEL)
-       sets[i].src_volatile = 1;
+       {
+         /* Do not record result of a non-volatile inline asm with
+            more than one result.  */
+         if (n_sets > 1)
+           sets[i].src_volatile = 1;
+
+         int j, lim = XVECLEN (x, 0);
+         for (j = 0; j < lim; j++)
+           {
+             rtx y = XVECEXP (x, 0, j);
+             /* And do not record result of a non-volatile inline asm
+                with "memory" clobber.  */
+             if (GET_CODE (y) == CLOBBER && MEM_P (XEXP (y, 0)))
+               {
+                 sets[i].src_volatile = 1;
+                 break;
+               }
+           }
+       }
 
 #if 0
       /* It is no longer clear why we used to do this, but it doesn't
@@ -5238,8 +5255,8 @@ cse_insn (rtx insn)
            ;
 
          /* Look for a substitution that makes a valid insn.  */
-         else if (validate_unshare_change
-                    (insn, &SET_SRC (sets[i].rtl), trial, 0))
+         else if (validate_unshare_change (insn, &SET_SRC (sets[i].rtl),
+                                           trial, 0))
            {
              rtx new_rtx = canon_reg (SET_SRC (sets[i].rtl), insn);
 
@@ -5600,6 +5617,12 @@ cse_insn (rtx insn)
                  }
                elt = insert (src, classp, sets[i].src_hash, mode);
                elt->in_memory = sets[i].src_in_memory;
+               /* If inline asm has any clobbers, ensure we only reuse
+                  existing inline asms and never try to put the ASM_OPERANDS
+                  into an insn that isn't inline asm.  */
+               if (GET_CODE (src) == ASM_OPERANDS
+                   && GET_CODE (x) == PARALLEL)
+                 elt->cost = MAX_COST;
                sets[i].src_elt = classp = elt;
              }
            if (sets[i].src_const && sets[i].src_const_elt == 0
@@ -5913,6 +5936,9 @@ cse_insn (rtx insn)
                      }
                    src_elt = insert (new_src, classp, src_hash, new_mode);
                    src_elt->in_memory = elt->in_memory;
+                   if (GET_CODE (new_src) == ASM_OPERANDS
+                       && elt->cost == MAX_COST)
+                     src_elt->cost = MAX_COST;
                  }
                else if (classp && classp != src_elt->first_same_value)
                  /* Show that two things that we've seen before are
index d063440f0146e29070ceec0f85d957344e5f4baf..594cf32692addeded8276116b772891846a76f9f 100644 (file)
@@ -1,6 +1,23 @@
 2015-02-01  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2015-01-23  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/63637
+       PR rtl-optimization/60663
+       * gcc.dg/pr63637-1.c: New test.
+       * gcc.dg/pr63637-2.c: New test.
+       * gcc.dg/pr63637-3.c: New test.
+       * gcc.dg/pr63637-4.c: New test.
+       * gcc.dg/pr63637-5.c: New test.
+       * gcc.dg/pr63637-6.c: New test.
+       * gcc.target/i386/pr63637-1.c: New test.
+       * gcc.target/i386/pr63637-2.c: New test.
+       * gcc.target/i386/pr63637-3.c: New test.
+       * gcc.target/i386/pr63637-4.c: New test.
+       * gcc.target/i386/pr63637-5.c: New test.
+       * gcc.target/i386/pr63637-6.c: New test.
+
        2015-01-20  Jakub Jelinek  <jakub@redhat.com>
 
        PR debug/64663
diff --git a/gcc/testsuite/gcc.dg/pr63637-1.c b/gcc/testsuite/gcc.dg/pr63637-1.c
new file mode 100644 (file)
index 0000000..7a716f9
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/63637 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+  int a, b, c;
+  asm ("# Magic instruction" : "=r" (a));
+  asm ("# Magic instruction" : "=r" (b));
+  asm ("# Magic instruction" : "=r" (c));
+  return a + b + c;
+}
+
+/* { dg-final { scan-assembler-times "# Magic instruction" 1 } } */
diff --git a/gcc/testsuite/gcc.dg/pr63637-2.c b/gcc/testsuite/gcc.dg/pr63637-2.c
new file mode 100644 (file)
index 0000000..44e9d7c
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/63637 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+  int a, b, c;
+  asm ("# Magic instruction" : "=r" (a) : "r" (0));
+  asm ("# Magic instruction" : "=r" (b) : "r" (0));
+  asm ("# Magic instruction" : "=r" (c) : "r" (0));
+  return a + b + c;
+}
+
+/* { dg-final { scan-assembler-times "# Magic instruction" 1 } } */
diff --git a/gcc/testsuite/gcc.dg/pr63637-3.c b/gcc/testsuite/gcc.dg/pr63637-3.c
new file mode 100644 (file)
index 0000000..51a2ff7
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/63637 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+  int a, b, c;
+  asm ("# Magic instruction" : "=r" (a) : : "memory");
+  asm ("# Magic instruction" : "=r" (b) : : "memory");
+  asm ("# Magic instruction" : "=r" (c) : : "memory");
+  return a + b + c;
+}
+
+/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */
diff --git a/gcc/testsuite/gcc.dg/pr63637-4.c b/gcc/testsuite/gcc.dg/pr63637-4.c
new file mode 100644 (file)
index 0000000..1a91483
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/63637 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+  int a, b, c;
+  asm ("# Magic instruction" : "=r" (a) : "r" (0) : "memory");
+  asm ("# Magic instruction" : "=r" (b) : "r" (0) : "memory");
+  asm ("# Magic instruction" : "=r" (c) : "r" (0) : "memory");
+  return a + b + c;
+}
+
+/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */
diff --git a/gcc/testsuite/gcc.dg/pr63637-5.c b/gcc/testsuite/gcc.dg/pr63637-5.c
new file mode 100644 (file)
index 0000000..fce8593
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/63637 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+  int a, b, c, d, e, f;
+  asm ("# Magic instruction" : "=r" (a), "=r" (d));
+  asm ("# Magic instruction" : "=r" (b), "=r" (e));
+  asm ("# Magic instruction" : "=r" (c), "=r" (f));
+  return a + b + c;
+}
+
+/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */
diff --git a/gcc/testsuite/gcc.dg/pr63637-6.c b/gcc/testsuite/gcc.dg/pr63637-6.c
new file mode 100644 (file)
index 0000000..1b997c4
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/63637 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+  int a, b, c, d, e, f;
+  asm ("# Magic instruction" : "=r" (a), "=r" (d) : "r" (0));
+  asm ("# Magic instruction" : "=r" (b), "=r" (e) : "r" (0));
+  asm ("# Magic instruction" : "=r" (c), "=r" (f) : "r" (0));
+  return a + b + c;
+}
+
+/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr63637-1.c b/gcc/testsuite/gcc.target/i386/pr63637-1.c
new file mode 100644 (file)
index 0000000..9cc9750
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/63637 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+  int a, b, c;
+  asm ("# Magic instruction" : "=r" (a) : : "eax");
+  asm ("# Magic instruction" : "=r" (b) : : "edx");
+  asm ("# Magic instruction" : "=r" (c) : : "ecx");
+  return a + b + c;
+}
+
+/* { dg-final { scan-assembler-times "# Magic instruction" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr63637-2.c b/gcc/testsuite/gcc.target/i386/pr63637-2.c
new file mode 100644 (file)
index 0000000..fc54900
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/63637 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+  int a, b, c;
+  asm ("# Magic instruction" : "=r" (a) : "r" (0) : "eax");
+  asm ("# Magic instruction" : "=r" (b) : "r" (0) : "edx");
+  asm ("# Magic instruction" : "=r" (c) : "r" (0) : "ecx");
+  return a + b + c;
+}
+
+/* { dg-final { scan-assembler-times "# Magic instruction" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr63637-3.c b/gcc/testsuite/gcc.target/i386/pr63637-3.c
new file mode 100644 (file)
index 0000000..4b631ce
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/63637 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+  int a, b, c;
+  asm ("# Magic instruction" : "=r" (a) : : "eax", "memory");
+  asm ("# Magic instruction" : "=r" (b) : : "edx", "memory");
+  asm ("# Magic instruction" : "=r" (c) : : "ecx", "memory");
+  return a + b + c;
+}
+
+/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr63637-4.c b/gcc/testsuite/gcc.target/i386/pr63637-4.c
new file mode 100644 (file)
index 0000000..7b36690
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/63637 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+  int a, b, c;
+  asm ("# Magic instruction" : "=r" (a) : "r" (0) : "eax", "memory");
+  asm ("# Magic instruction" : "=r" (b) : "r" (0) : "edx", "memory");
+  asm ("# Magic instruction" : "=r" (c) : "r" (0) : "ecx", "memory");
+  return a + b + c;
+}
+
+/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr63637-5.c b/gcc/testsuite/gcc.target/i386/pr63637-5.c
new file mode 100644 (file)
index 0000000..f0c79b7
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/63637 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+  int a, b, c, d, e, f;
+  asm ("# Magic instruction" : "=r" (a), "=r" (d) : : "eax");
+  asm ("# Magic instruction" : "=r" (b), "=r" (e) : : "edx");
+  asm ("# Magic instruction" : "=r" (c), "=r" (f) : : "ecx");
+  return a + b + c;
+}
+
+/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr63637-6.c b/gcc/testsuite/gcc.target/i386/pr63637-6.c
new file mode 100644 (file)
index 0000000..4b0b3ba
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/63637 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+  int a, b, c, d, e, f;
+  asm ("# Magic instruction" : "=r" (a), "=r" (d) : "r" (0) : "eax");
+  asm ("# Magic instruction" : "=r" (b), "=r" (e) : "r" (0) : "edx");
+  asm ("# Magic instruction" : "=r" (c), "=r" (f) : "r" (0) : "ecx");
+  return a + b + c;
+}
+
+/* { dg-final { scan-assembler-times "# Magic instruction" 3 } } */