This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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

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?  If so, ok to install
if bootstrap and regtest on amd64-linux-gnu and i686-pc-linux-gnu
succeed?

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 09:10:00 -0000
@@ -3689,15 +3689,22 @@ 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 = GET_MODE (SUBREG_REG (x));
+
+		  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));
 
-		  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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]