diff mbox series

Fix ICE with _Complex type punning expansion (PR middle-end/89412)

Message ID 20190220223214.GQ2135@tucnak
State New
Headers show
Series Fix ICE with _Complex type punning expansion (PR middle-end/89412) | expand

Commit Message

Jakub Jelinek Feb. 20, 2019, 10:32 p.m. UTC
Hi!

On the following testcase we ICE in simplify_gen_subreg, when result has
BLKmode and we want to convert it to some complex mode (e.g. DCmode or
in theory XCmode or TCmode too).
Such SUBREGs are invalid, but BLKmode can only live in memory and when it
is a MEM, we don't really need to create a subreg, we can change_address
and just load it as if it is a complex MEM.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-02-20  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/89412
	* expr.c (expand_assignment): If result is a MEM, use change_address
	instead of simplify_gen_subreg.

	* gcc.c-torture/compile/pr89412.c: New test.


	Jakub

Comments

Jeff Law Feb. 20, 2019, 10:53 p.m. UTC | #1
On 2/20/19 3:32 PM, Jakub Jelinek wrote:
> Hi!
> 
> On the following testcase we ICE in simplify_gen_subreg, when result has
> BLKmode and we want to convert it to some complex mode (e.g. DCmode or
> in theory XCmode or TCmode too).
> Such SUBREGs are invalid, but BLKmode can only live in memory and when it
> is a MEM, we don't really need to create a subreg, we can change_address
> and just load it as if it is a complex MEM.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> 2019-02-20  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR middle-end/89412
> 	* expr.c (expand_assignment): If result is a MEM, use change_address
> 	instead of simplify_gen_subreg.
> 
> 	* gcc.c-torture/compile/pr89412.c: New test.
OK
Jeff
diff mbox series

Patch

--- gcc/expr.c.jj	2019-02-16 12:19:37.602192262 +0100
+++ gcc/expr.c	2019-02-20 16:29:39.261497006 +0100
@@ -5211,9 +5211,13 @@  expand_assignment (tree to, tree from, b
 		}
 	      else
 		{
-		  rtx from_rtx
-		    = simplify_gen_subreg (to_mode, result,
-					   TYPE_MODE (TREE_TYPE (from)), 0);
+		  rtx from_rtx;
+		  if (MEM_P (result))
+		    from_rtx = change_address (result, to_mode, NULL_RTX);
+		  else
+		    from_rtx
+		      = simplify_gen_subreg (to_mode, result,
+					     TYPE_MODE (TREE_TYPE (from)), 0);
 		  if (from_rtx)
 		    {
 		      emit_move_insn (XEXP (to_rtx, 0),
--- gcc/testsuite/gcc.c-torture/compile/pr89412.c.jj	2019-02-20 16:30:47.722387639 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr89412.c	2019-02-20 16:31:29.288714080 +0100
@@ -0,0 +1,16 @@ 
+/* PR middle-end/89412 */
+
+struct S { double a, b; } d;
+int e;
+double f;
+
+void
+foo ()
+{
+  _Complex double h;
+  while (e)
+    {
+      f = h;
+      *(struct S *) &h = d;
+    }
+}