[PATCH] ICE caused by calling simplify_subreg with BLKmode

Andreas Krebbel Andreas.Krebbel@de.ibm.com
Mon Nov 6 12:31:00 GMT 2006


Hi,

mainline gcc currently doesn't bootstrap on s390 and s390x.  The problem
is an ICE in simplify_subreg which is triggered by BLKmode given as
outermode.  The source operand is BLKmode since a memcpy pattern is used
to implement the move from a literal pool location to a variable residing in
memory as well.

The attached patch simply avoids calling simplify_subreg when the source operand
is BLKmode.  Perhaps we also could add some magic which derives a mode from
the length attribute of the memcpy but I'm not sure whether that's worth the trouble.

Bootstrapped on s390 and s390x.
Testsuite still running.

OK for mainline given that no testsuite regression occurs.

Bye,

-Andreas-


2006-11-06  Andreas Krebbel  <krebbel1@de.ibm.com>

	* simplify-rtx.c (avoid_constant_pool_reference): Don't call 
	simplify_subreg with BLKmode outer mode.


2006-11-06  Andreas Krebbel  <krebbel1@de.ibm.com>

	* gcc.dg/20061106-1.c: New testcase.


Index: gcc/simplify-rtx.c
===================================================================
*** gcc/simplify-rtx.c.orig	2006-11-06 10:29:23.000000000 +0100
--- gcc/simplify-rtx.c	2006-11-06 10:35:08.000000000 +0100
*************** avoid_constant_pool_reference (rtx x)
*** 183,199 ****
        c = get_pool_constant (addr);
        cmode = get_pool_mode (addr);
  
        /* If we're accessing the constant in a different mode than it was
           originally stored, attempt to fix that up via subreg simplifications.
           If that fails we have no choice but to return the original memory.  */
!       if (offset != 0 || cmode != GET_MODE (x))
!         {
            rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
            if (tem && CONSTANT_P (tem))
              return tem;
          }
-       else
-         return c;
      }
  
    return x;
--- 183,200 ----
        c = get_pool_constant (addr);
        cmode = get_pool_mode (addr);
  
+       if (offset == 0 && cmode == GET_MODE (x))
+ 	return c;
+ 
        /* If we're accessing the constant in a different mode than it was
           originally stored, attempt to fix that up via subreg simplifications.
           If that fails we have no choice but to return the original memory.  */
!       if (GET_MODE (x) != BLKmode)
! 	{
            rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
            if (tem && CONSTANT_P (tem))
              return tem;
          }
      }
  
    return x;
Index: gcc/testsuite/gcc.dg/20061106-1.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/20061106-1.c	2006-11-06 10:45:59.000000000 +0100
***************
*** 0 ****
--- 1,17 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O1" } */
+ 
+ /* This assignment might be implemented with a mem copy from the
+    literal pool with two BLKmode operands.  This produced an ICE on S/390
+    since simplify_subreg was called for such a BLKmode operand.  */
+ 
+ struct a
+ {
+   unsigned int b:24;
+ };
+ 
+ void
+ foo (struct a *t)
+ {
+   t->b = 32;
+ }



More information about the Gcc-patches mailing list