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