[PATCH] Combine x >> 8 << 8
Zdenek Dvorak
rakdver@atrey.karlin.mff.cuni.cz
Wed Jul 23 19:15:00 GMT 2003
Hello,
in the following testcase
short kernel (short t1)
{
t1 >>= 8; t1 <<= 8;
return t1;
}
combiner does not manage to fold the shifts into (t1 & 0xff00), because
it first expresses the first shift as sign_extract and then it does not
manage to simplify it when substituted into the second shift. The patch
fixes it.
Zdenek
* combine.c (force_to_mode): Allow narrowing of right shifts if
possible. Simplify ashift by constant.
Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.323.2.16
diff -c -3 -p -r1.323.2.16 combine.c
*** combine.c 21 Jun 2003 18:44:42 -0000 1.323.2.16
--- combine.c 23 Jul 2003 18:00:00 -0000
*************** force_to_mode (x, mode, mask, reg, just_
*** 6930,6939 ****
? mode : GET_MODE (x));
/* It is not valid to do a right-shift in a narrower mode
! than the one it came in with. */
if ((code == LSHIFTRT || code == ASHIFTRT)
! && GET_MODE_BITSIZE (mode) < GET_MODE_BITSIZE (GET_MODE (x)))
! op_mode = GET_MODE (x);
/* Truncate MASK to fit OP_MODE. */
if (op_mode)
--- 6930,6965 ----
? mode : GET_MODE (x));
/* It is not valid to do a right-shift in a narrower mode
! than the one it came in with, unless the bits forgotten due to
! it are irrelevant. */
if ((code == LSHIFTRT || code == ASHIFTRT)
! && GET_MODE_BITSIZE (mode) < GET_MODE_BITSIZE (GET_MODE (x))
! && op_mode != GET_MODE (x))
! {
! if (GET_CODE (XEXP (x, 1)) == CONST_INT
! && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
! {
! unsigned HOST_WIDE_INT new_bits;
!
! if (code == LSHIFTRT)
! {
! new_bits = GET_MODE_MASK (GET_MODE (x)) & ~GET_MODE_MASK (mode);
! new_bits >>= INTVAL (XEXP (x, 1));
! }
! else if (GET_MODE_BITSIZE (GET_MODE (x)) < INTVAL (XEXP (x, 1)))
! new_bits = GET_MODE_MASK (GET_MODE (x));
! else
! {
! new_bits = GET_MODE_MASK (GET_MODE (x));
! new_bits &= ~(GET_MODE_MASK (mode) >> INTVAL (XEXP (x, 1)));
! }
!
! if ((new_bits & mask) != 0)
! op_mode = GET_MODE (x);
! }
! else
! op_mode = GET_MODE (x);
! }
/* Truncate MASK to fit OP_MODE. */
if (op_mode)
*************** force_to_mode (x, mode, mask, reg, just_
*** 7209,7215 ****
mask, reg, next_select));
if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
! x = gen_binary (code, op_mode, op0, XEXP (x, 1));
break;
case LSHIFTRT:
--- 7235,7246 ----
mask, reg, next_select));
if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0))
! {
! x = gen_binary (code, op_mode, op0, XEXP (x, 1));
! if (GET_CODE (XEXP (x, 1)) == CONST_INT)
! x = simplify_shift_const (x, GET_CODE (x), op_mode,
! XEXP (x, 0), INTVAL (XEXP (x, 1)));
! }
break;
case LSHIFTRT:
More information about the Gcc-patches
mailing list