This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
combine shift improvement
- To: gcc-patches at gcc dot gnu dot org
- Subject: combine shift improvement
- From: Richard Henderson <rth at cygnus dot com>
- Date: Mon, 29 May 2000 00:40:19 -0700
This is helpful for targets that define SHIFT_COUNT_TRUNCATED (about half)
and do not support subtraction *from* a constant (all but one):
To 5 bits, 64 - x == -x and 63 - x == ~x. Which of course should be
instantly recognizable as something that's done quite frequently when
performing double-word shifts.
Bootstrapped i686 and alphaev67
r~
* combine.c (force_to_mode) [MINUS]: Convert subtraction from
a constant to NEG or NOT when conditions allow.
Index: combine.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/combine.c,v
retrieving revision 1.132
diff -c -p -d -r1.132 combine.c
*** combine.c 2000/05/29 07:29:02 1.132
--- combine.c 2000/05/29 07:29:37
*************** force_to_mode (x, mode, mask, reg, just_
*** 6846,6856 ****
/* ... fall through ... */
- case MINUS:
case MULT:
/* For PLUS, MINUS and MULT, we need any bits less significant than the
most significant bit in MASK since carries from those bits will
affect the bits we are interested in. */
mask = fuller_mask;
goto binop;
--- 6846,6877 ----
/* ... fall through ... */
case MULT:
/* For PLUS, MINUS and MULT, we need any bits less significant than the
most significant bit in MASK since carries from those bits will
affect the bits we are interested in. */
+ mask = fuller_mask;
+ goto binop;
+
+ case MINUS:
+ /* If X is (minus C Y) where C's least set bit is larger than any bit
+ in the mask, then we may replace with (neg Y). */
+ if (GET_CODE (XEXP (x, 0)) == CONST_INT
+ && (INTVAL (XEXP (x, 0)) & -INTVAL (XEXP (x, 0))) > mask)
+ {
+ x = gen_unary (NEG, GET_MODE (x), GET_MODE (x), XEXP (x, 1));
+ return force_to_mode (x, mode, mask, reg, next_select);
+ }
+
+ /* Similarly, if C contains every bit in the mask, then we may
+ replace with (not Y). */
+ if (GET_CODE (XEXP (x, 0)) == CONST_INT
+ && (INTVAL (XEXP (x, 0)) | mask) == INTVAL (XEXP (x, 0)))
+ {
+ x = gen_unary (NOT, GET_MODE (x), GET_MODE (x), XEXP (x, 1));
+ return force_to_mode (x, mode, mask, reg, next_select);
+ }
+
mask = fuller_mask;
goto binop;