On May 6, 2018 7:59:33 PM GMT+02:00, Jakub Jelinek <ja...@redhat.com> wrote:
>Hi!
>
>At expansion time, we in various cases choose to assign_temp and ICE
>in that case on any expressions with TREE_ADDRESSABLE types.  We don't
>want
>to create any temporaries for such types, the var needs to live in
>memory
>and if the constraint doesn't allow mem, we should just reject it as
>invalid.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for
>trunk/8.2?

OK. 

Richard. 

>2018-05-06  Jakub Jelinek  <ja...@redhat.com>
>
>       PR c++/85659
>       * cfgexpand.c (expand_asm_stmt): Don't create a temporary if
>       the type is addressable.  Don't force op into register if it has
>       BLKmode.
>
>       * g++.dg/ext/asm14.C: New test.
>       * g++.dg/ext/asm15.C: New test.
>       * g++.dg/ext/asm16.C: New test.
>
>--- gcc/cfgexpand.c.jj 2018-03-27 12:54:43.000000000 +0200
>+++ gcc/cfgexpand.c    2018-05-05 13:28:44.037551377 +0200
>@@ -3044,14 +3044,14 @@ expand_asm_stmt (gasm *stmt)
> 
>       generating_concat_p = 0;
> 
>-      if ((TREE_CODE (val) == INDIRECT_REF
>-         && allows_mem)
>+      if ((TREE_CODE (val) == INDIRECT_REF && allows_mem)
>         || (DECL_P (val)
>             && (allows_mem || REG_P (DECL_RTL (val)))
>             && ! (REG_P (DECL_RTL (val))
>                   && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))
>         || ! allows_reg
>-        || is_inout)
>+        || is_inout
>+        || TREE_ADDRESSABLE (type))
>       {
>         op = expand_expr (val, NULL_RTX, VOIDmode,
>                           !allows_reg ? EXPAND_MEMORY : EXPAND_WRITE);
>@@ -3060,7 +3060,7 @@ expand_asm_stmt (gasm *stmt)
> 
>         if (! allows_reg && !MEM_P (op))
>           error ("output number %d not directly addressable", i);
>-        if ((! allows_mem && MEM_P (op))
>+        if ((! allows_mem && MEM_P (op) && GET_MODE (op) != BLKmode)
>             || GET_CODE (op) == CONCAT)
>           {
>             rtx old_op = op;
>--- gcc/testsuite/g++.dg/ext/asm14.C.jj        2018-05-05 13:15:50.099258834
>+0200
>+++ gcc/testsuite/g++.dg/ext/asm14.C   2018-05-05 13:19:09.717327528
>+0200
>@@ -0,0 +1,10 @@
>+// PR c++/85659
>+// { dg-do compile }
>+
>+struct S { S (); ~S (); int s; };
>+
>+void
>+foo (S &s)
>+{
>+  __asm volatile ("" : "+m,r" (s) : : "memory");
>+}
>--- gcc/testsuite/g++.dg/ext/asm15.C.jj        2018-05-05 13:15:56.656261090
>+0200
>+++ gcc/testsuite/g++.dg/ext/asm15.C   2018-05-05 13:19:15.125329389
>+0200
>@@ -0,0 +1,10 @@
>+// PR c++/85659
>+// { dg-do compile }
>+
>+struct S { S (); ~S (); int s; };
>+
>+void
>+foo (S &s)
>+{
>+  __asm volatile ("" : "+r" (s) : : "memory");        // { dg-error "" }
>+}
>--- gcc/testsuite/g++.dg/ext/asm16.C.jj        2018-05-05 13:28:03.448530441
>+0200
>+++ gcc/testsuite/g++.dg/ext/asm16.C   2018-05-05 13:28:21.068539532
>+0200
>@@ -0,0 +1,10 @@
>+// PR c++/85659
>+// { dg-do compile }
>+
>+struct S { S (); ~S (); int s[64]; } s;
>+
>+void
>+foo ()
>+{
>+  __asm volatile ("" : "=r" (s) : : "memory");        // { dg-error "" }
>+}
>
>       Jakub

Reply via email to