diff mbox series

Don't create temporaries on "+m,r" with addressable type (PR c++/85659)

Message ID 20180506175933.GB8577@tucnak
State New
Headers show
Series Don't create temporaries on "+m,r" with addressable type (PR c++/85659) | expand

Commit Message

Jakub Jelinek May 6, 2018, 5:59 p.m. UTC
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?

2018-05-06  Jakub Jelinek  <jakub@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.


	Jakub

Comments

Richard Biener May 6, 2018, 7:54 p.m. UTC | #1
On May 6, 2018 7:59:33 PM GMT+02:00, Jakub Jelinek <jakub@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  <jakub@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
diff mbox series

Patch

--- 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 "" }
+}