https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89752

--- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Actually can't bisect, as gcc 8 I have installed is no longer able to build
r215000 or revisions around it (some error on wide-int.h:
../../gcc/wide-int.h:372:10: error: too many template-parameter-lists
   struct binary_traits <T1, T2, FLEXIBLE_PRECISION, FLEXIBLE_PRECISION>
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
etc.).

That said, if we want to fix the:
struct A { A (); ~A (); short c; };

void
foo ()
{
  A a0, a1;
  __asm volatile ("" : "+rm" (a0), "+rm" (a1));
}
in the provided testcase, we could use:
--- 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));

which is something we already do for the input args, just for some strange
reason not for output args as well (if we wanted to backport it, I'd leave the
error part out).

That said, because users can write even that:
struct A { A (); ~A (); short c; };

void
foo ()
{
  A a0, a1;
  __asm volatile ("" : "=rm" (a0), "=rm" (a1) : "0" (a0), "1" (a1));
}
we need something in LRA too, that will simply treat BLKmode matching
constraints when both registers and memory are allowed as if only memory was
allowed.

Reply via email to