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]

[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
--


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