Patchwork Fix expansion ICE with VOIDmode MEM (PR middle-end/46388)

login
register
mail settings
Submitter Jakub Jelinek
Date Nov. 10, 2010, 11:21 p.m.
Message ID <20101110232124.GZ29412@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/70727/
State New
Headers show

Comments

Jakub Jelinek - Nov. 10, 2010, 11:21 p.m.
Hi!

On IA-64 the attached testcase segfaults, because the DECL_EXTERNAL
var u has incomplete type and during expansion we create VOIDmode MEM
for it (that VAR_DECL is the get_inner_reference result, we of course
have non-VOIDmode mode we are accessing it through in the MEM_REF).
In some versions of the store_field code which happens to be used
on this testcase on ia64 the VOIDmode MEM leads to ICEs.

I think we just should avoid having VOIDmode MEM around whenever possible,
the following patch fixes it by using the MEM_REF access mode instead
(alternatively we could always use BLKmode for it).

Bootstrapped/regtested on x86_64-linux and i686-linux, tested on the
testcase with cross to ia64-linux.  Ok for trunk?

2010-11-10  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/46388
	* expr.c (expand_assignment): If to_rtx is a VOIDmode MEM, use
	mode1 mode for it.
	(expand_expr_real_1): Similarly for op0.

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


	Jakub
Richard Henderson - Nov. 11, 2010, 12:04 a.m.
On 11/10/2010 03:21 PM, Jakub Jelinek wrote:
> I think we just should avoid having VOIDmode MEM around whenever possible,
> the following patch fixes it by using the MEM_REF access mode instead
> (alternatively we could always use BLKmode for it).

I prefer we create the mem with BLKmode.


r~

Patch

--- gcc/expr.c.jj	2010-11-09 13:58:30.000000000 +0100
+++ gcc/expr.c	2010-11-10 11:37:53.000000000 +0100
@@ -4260,10 +4260,11 @@  expand_assignment (tree to, tree from, b
       to_rtx = expand_normal (tem);
 
       /* If the bitfield is volatile, we want to access it in the
-	 field's mode, not the computed mode.  */
-      if (volatilep
-	  && GET_CODE (to_rtx) == MEM
-	  && flag_strict_volatile_bitfields > 0)
+	 field's mode, not the computed mode.
+	 Similarly, if MEM has a VOIDmode (external with incomplete type).  */
+      if (MEM_P (to_rtx)
+	  && ((volatilep && flag_strict_volatile_bitfields > 0)
+	      || GET_MODE (to_rtx) == VOIDmode))
 	to_rtx = adjust_address (to_rtx, mode1, 0);
  
       if (offset != 0)
@@ -9013,10 +9014,12 @@  expand_expr_real_1 (tree exp, rtx target
 
 
 	/* If the bitfield is volatile, we want to access it in the
-	   field's mode, not the computed mode.  */
-	if (volatilep
-	    && GET_CODE (op0) == MEM
-	    && flag_strict_volatile_bitfields > 0)
+	   field's mode, not the computed mode.
+	   Similarly, if MEM has a VOIDmode (external with incomplete
+	   type).  */
+	if (MEM_P (op0)
+	    && ((volatilep && flag_strict_volatile_bitfields > 0)
+		|| GET_MODE (op0) == VOIDmode))
 	  op0 = adjust_address (op0, mode1, 0);
 
 	mode2
--- gcc/testsuite/gcc.c-torture/compile/pr46388.c.jj	2010-11-10 11:45:52.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr46388.c	2010-11-10 11:45:37.000000000 +0100
@@ -0,0 +1,14 @@ 
+/* PR middle-end/46388 */
+
+struct S;
+struct T
+{
+  struct S *t;
+};
+extern struct S s, u;
+
+void
+foo (void)
+{
+  ((struct T *) &u)->t = &s;
+}