[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