------- 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 <[EMAIL PROTECTED]> 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  <[EMAIL PROTECTED]>

        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  <[EMAIL PROTECTED]>

        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   [EMAIL PROTECTED], gcc.gnu.org}
Free Software Evangelist  [EMAIL PROTECTED], gnu.org}


-- 


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

Reply via email to