This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Committed] (and (sign_extend X) C) -> (zero_extend (and X C))
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 13 Jan 2005 19:39:23 -0700 (MST)
- Subject: [Committed] (and (sign_extend X) C) -> (zero_extend (and X C))
The following patch is the next iteration towards resolving bugzilla
PR middle-end/19154 which is a mainline performance regression on AVR.
The patch below implements the transformation (and (sign_extend X) C)
into the equivalent (zero_extend (and X C)) if C has no non-zero bits
outside of X's mode. For example, in one of this PR's examples it
allows us to transform
(and:HI (sign_extend:HI (reg:QI X)) (const_int 1))
into
(zero_extend:HI (and:QI (reg:QI X) (const_int 1))
which has the twin advantages that the AND operation is now performed
in a narrower mode, and that zero_extend is cheaper on many platforms
than sign_extend. This normalization also help's combine recognize
zero_extract idioms.
The following patch has been tested on i686-pc-linux-gnu by a full
"make bootstrap", all default languages, and regression tested by a
top-level "make -k check" with no new failures.
Committed to mainline CVS.
2005-01-13 Roger Sayle <roger@eyesopen.com>
* simplify-rtx.c (simplify_binary_operation) <AND>: Optimize
(and (sign_extend X) C) into (zero_extend (and X C)).
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.221
diff -c -3 -p -r1.221 simplify-rtx.c
*** simplify-rtx.c 7 Jan 2005 00:47:13 -0000 1.221
--- simplify-rtx.c 14 Jan 2005 01:15:01 -0000
*************** simplify_binary_operation (enum rtx_code
*** 1910,1915 ****
--- 1910,1932 ----
&& ! side_effects_p (op0)
&& GET_MODE_CLASS (mode) != MODE_CC)
return const0_rtx;
+
+ /* Transform (and (extend X) C) into (zero_extend (and X C)) if
+ there are no non-zero bits of C outside of X's mode. */
+ if ((GET_CODE (op0) == SIGN_EXTEND
+ || GET_CODE (op0) == ZERO_EXTEND)
+ && GET_CODE (trueop1) == CONST_INT
+ && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
+ && (~GET_MODE_MASK (GET_MODE (XEXP (op0, 0)))
+ & INTVAL (trueop1)) == 0)
+ {
+ enum machine_mode imode = GET_MODE (XEXP (op0, 0));
+ tem = simplify_gen_binary (AND, imode, XEXP (op0, 0),
+ gen_int_mode (INTVAL (trueop1),
+ imode));
+ return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
+ }
+
/* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
((A & N) + B) & M -> (A + B) & M
Similarly if (N & M) == 0,
Roger
--