[Bug middle-end/20491] [4.0/4.1 Regression] internal compiler error: in subreg_regno_offset, at rtlanal.c:3042

aoliva at redhat dot com gcc-bugzilla@gcc.gnu.org
Thu Mar 24 10:46:00 GMT 2005


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-24 10:46 -------
Subject: Re: [PR middle-end/20491] combine generates bad subregs

On Mar 24, 2005, Alexandre Oliva <aoliva@redhat.com> wrote:

> Combine doesn't ensure the subregs it generates are valid.  In most
> cases, insn recog will reject the invalid subregs, or reload will
> somehow make them fit, but if the constraint of the insn or the asm
> operand is "X", this won't work, so I think we're better off ensuring
> we don't ever introduce subregs of non-REGs.

> Does this look like a reasonable change to make?

Ugh.  It failed building libgcc for stage 1, after simplifying
(subreg:QI (subreg:SI (reg:HI))) to (subreg:QI (reg:HI)), leaving
op0_mode set to SImode, causing an error in combine_simplify_rtx(),
when it called simplify_subreg with the wrong mode.

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR middle-end/20491
	* combine.c (subst): Make sure we don't create invalid subregs.

Index: gcc/combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.484
diff -u -p -r1.484 combine.c
--- gcc/combine.c 22 Mar 2005 03:48:44 -0000 1.484
+++ gcc/combine.c 24 Mar 2005 10:01:17 -0000
@@ -3689,15 +3689,24 @@ subst (rtx x, rtx from, rtx to, int in_d
 	      if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx)
 		return new;
 
-	      if (GET_CODE (x) == SUBREG
-		  && (GET_CODE (new) == CONST_INT
-		      || GET_CODE (new) == CONST_DOUBLE))
+	      /* If we changed the reg of a subreg, make sure it's
+		 still valid.  For anything but a REG, require the
+		 SUBREG to be simplified out.  */
+
+	      if (GET_CODE (x) == SUBREG && new != SUBREG_REG (x))
 		{
 		  enum machine_mode mode = GET_MODE (x);
+		  enum machine_mode submode = op0_mode;
+
+		  if (GET_CODE (new) == REG)
+		    x = simplify_gen_subreg (mode, new, submode,
+					     SUBREG_BYTE (x));
+		  else
+		    x = simplify_subreg (mode, new, submode,
+					 SUBREG_BYTE (x));
+
+		  op0_mode = VOIDmode;
 
-		  x = simplify_subreg (GET_MODE (x), new,
-				       GET_MODE (SUBREG_REG (x)),
-				       SUBREG_BYTE (x));
 		  if (! x)
 		    x = gen_rtx_CLOBBER (mode, const0_rtx);
 		}
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR middle-end/20491
	* gcc.dg/asm-subreg-1.c: New.

Index: gcc/testsuite/gcc.dg/asm-subreg-1.c
===================================================================
RCS file: gcc/testsuite/gcc.dg/asm-subreg-1.c
diff -N gcc/testsuite/gcc.dg/asm-subreg-1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/asm-subreg-1.c 24 Mar 2005 09:10:14 -0000
@@ -0,0 +1,14 @@
+/* PR middle-end/20491 */
+
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+/* Combine used to introduce invalid subregs for the asm input.  */
+
+volatile unsigned short _const_32 [4] = {1,2,3,4};
+void
+evas_common_convert_yuv_420p_601_rgba()
+{
+  __asm__ __volatile__ ("" : : "X" (*_const_32));
+}
+

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20491



More information about the Gcc-bugs mailing list