This is the mail archive of the gcc-patches@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]

[patch] Remove an unnecessary subreg in combine.


Hi,

Attached is a patch to remove an unnecessary subreg in combine in
certain situation.

When I have code like

long x;
if (x & 1)
  foo ();

the combiner suggests

(set (cc0)
     (subreg:HI (zero_extract:SI (reg:SI 17)
                                 (const_int 1)
                                 (const_int 0))))

This fails to be recognized, but if we remove subreg like

(set (cc0)
     (zero_extract:SI (reg:SI 17)
                      (const_int 1)
                      (const_int 0)))

then we have a perfectly recognizable rtx.

The patch attempts to remove such a subreg.  Specifically, if all the
nonzero bits of the inner expression of a subreg survives through the
subreg, then we can remove the subreg.  For simplicity, I do not
consider

1. a paradoxical subreg,
2. a subreg with its LSB other than 0, or
3. when the sign bit after a subreg may matter.

Testing with newlib on h8300 shows so many instances of 'and' insn
replaced with 'btst', a bit test insn.

Regression tested on h8300 port.  OK to apply?

Thanks,

Kazu Hirata

2002-05-24  Kazu Hirata  <kazu@cs.umass.edu>

	* combine.c (simplify_set): Remove an unnecessary subreg.

Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.292
diff -u -r1.292 combine.c
--- combine.c	23 May 2002 19:23:38 -0000	1.292
+++ combine.c	24 May 2002 15:08:36 -0000
@@ -5160,6 +5160,28 @@
       src = SET_SRC (x), dest = SET_DEST (x);
     }
 
+#ifdef HAVE_cc0
+  /* If we have (set (cc0) (subreg ...)), we try to remove the subreg
+     in SRC.  */
+  if (dest == cc0_rtx
+      && GET_CODE (src) == SUBREG
+      && subreg_lsb (src) == 0
+      && (GET_MODE_BITSIZE (GET_MODE (src))
+	  < GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (src)))))
+    {
+      rtx inner = SUBREG_REG (src);
+      enum machine_mode inner_mode = GET_MODE (inner);
+
+      /* Here we make sure that we don't have a sign bit on.  */
+      if (nonzero_bits (inner, inner_mode)
+	  < (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (inner_mode) - 1))
+	{
+	  SUBST (SET_SRC (x), inner);
+	  src = SET_SRC (x);
+	}
+    }
+#endif
+
 #ifdef LOAD_EXTEND_OP
   /* If we have (set FOO (subreg:M (mem:N BAR) 0)) with M wider than N, this
      would require a paradoxical subreg.  Replace the subreg with a


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