This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Remove an unnecessary subreg in combine.
- From: Kazu Hirata <kazu at cs dot umass dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 24 May 2002 12:01:59 -0400 (EDT)
- Subject: [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