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 <[email protected]>
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