Hi!

For input arguments, we do:
      /* If we can't make copies, we can only accept memory.  */
      if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link))))
        {
          if (allows_mem)
            allows_reg = 0;
          else
            {
              error ("impossible constraint in %<asm%>");
              error ("non-memory input %d must stay in memory", i);
              return GS_ERROR;
            }
        }
The following patch does the same thing for output operands as well.
For the cases where !allows_mem, that will just result in one extra error
explaining what's going on (previously one would get the
impossible constraint in %<asm%> error during vregs pass, now it gets
during gimplification + the extra error too), and if allows_mem,
it will for the + case make sure we get "=rm" (x) ... : "rm" (x) instead
of "=rm" (x) ... : "0" (x) that LRA ICEs on.

While the LRA ICE needs to be fixed in any case (one can still reproduce it
with
  __asm volatile ("" : "=rm" (a0), "=rm" (a1) : "0" (a0), "1" (a1));
), this patch opens the possibility to accept "+rm" (a0) and reject
"=rm" (a0) ... "0" (a0) if reload can't prove it is the same address.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-03-18  Jakub Jelinek  <ja...@redhat.com>

        PR target/89752
        * gimplify.c (gimplify_asm_expr): For output argument with
        TREE_ADDRESSABLE type, clear allows_reg if it allows memory, otherwise
        diagnose error.

        * g++.dg/ext/asm15.C: Check for particular diagnostic wording.
        * g++.dg/ext/asm16.C: Likewise.
        * g++.dg/ext/asm17.C: New test.

--- gcc/gimplify.c.jj   2019-03-07 20:45:39.168938360 +0100
+++ gcc/gimplify.c      2019-03-18 16:18:16.515466234 +0100
@@ -6155,6 +6155,19 @@ gimplify_asm_expr (tree *expr_p, gimple_
          is_inout = false;
        }
 
+      /* If we can't make copies, we can only accept memory.  */
+      if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link))))
+       {
+         if (allows_mem)
+           allows_reg = 0;
+         else
+           {
+             error ("impossible constraint in %<asm%>");
+             error ("non-memory output %d must stay in memory", i);
+             return GS_ERROR;
+           }
+       }
+
       if (!allows_reg && allows_mem)
        mark_addressable (TREE_VALUE (link));
 
--- gcc/testsuite/g++.dg/ext/asm15.C.jj 2018-05-06 23:13:33.252652046 +0200
+++ gcc/testsuite/g++.dg/ext/asm15.C    2019-03-18 18:00:48.907456236 +0100
@@ -6,5 +6,6 @@ struct S { S (); ~S (); int s; };
 void
 foo (S &s)
 {
-  __asm volatile ("" : "+r" (s) : : "memory"); // { dg-error "" }
+  __asm volatile ("" : "+r" (s) : : "memory"); // { dg-error "impossible 
constraint" }
+                                               // { dg-error "must stay in 
memory" "" { target *-*-* } .-1 }
 }
--- gcc/testsuite/g++.dg/ext/asm16.C.jj 2018-05-06 23:13:33.252652046 +0200
+++ gcc/testsuite/g++.dg/ext/asm16.C    2019-03-18 18:00:35.978664187 +0100
@@ -6,5 +6,6 @@ struct S { S (); ~S (); int s[64]; } s;
 void
 foo ()
 {
-  __asm volatile ("" : "=r" (s) : : "memory"); // { dg-error "" }
+  __asm volatile ("" : "=r" (s) : : "memory"); // { dg-error "impossible 
constraint" }
+                                               // { dg-error "must stay in 
memory" "" { target *-*-* } .-1 }
 }
--- gcc/testsuite/g++.dg/ext/asm17.C.jj 2019-03-18 17:57:44.409424473 +0100
+++ gcc/testsuite/g++.dg/ext/asm17.C    2019-03-18 17:58:32.414651932 +0100
@@ -0,0 +1,11 @@
+// PR target/89752
+// { dg-do compile }
+
+struct A { A (); ~A (); short c; };
+
+void
+foo ()
+{
+  A a0, a1;
+  __asm volatile ("" : "+rm" (a0), "+rm" (a1));
+}

        Jakub

Reply via email to