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]

Re: patch to stop GCC from shifting by a negative number


Here is a new patch to stop GCC from shifting by a negative number in
trunc_int_for_mode.  It is basically Geoff Keating's patch
(http://gcc.gnu.org/ml/gcc-patches/2002-08/msg00853.html) that ensures
we don't call trunc_int_for_mode with VOIDmode but with a couple of
extra changes in combine.c to stop us from calling it with Vector or
Complex modes either.

With Geoff's original patch I was failing
gcc.c-torture/execute/20020227-1.c and gcc.c-torture/compile/simd-1.c,
with them it passes the test suite with no regressions.

Here is a patch that includes both my changes and Geoff's.

Steve Ellcey
sje@cup.hp.com


2002-08-12  Geoffrey Keating  <geoffk@redhat.com>
	    Steve Ellcey  <sje@cup.hp.com>

	* explow.c (trunc_int_for_mode): Abort when the mode is not
	an integer mode.
	* combine.c (expand_compound_operation): Don't expand Vector
	or Complex modes into shifts.
	(expand_field_assignment): Don't do bitwise arithmatic and
	shifts on Vector or Complex modes.
	(simplify_comparison): Don't call trunc_int_for_mode
	for VOIDmode.
	* recog.c (general_operand): Likewise.
	(immediate_operand): Likewise.
	(nonmemory_operand): Likewise.


*** gcc.orig/gcc/explow.c	Fri Aug 16 12:12:13 2002
--- gcc/gcc/explow.c	Fri Aug 16 12:12:55 2002
*************** trunc_int_for_mode (c, mode)
*** 49,54 ****
--- 49,59 ----
  {
    int width = GET_MODE_BITSIZE (mode);
  
+   /* You want to truncate to a _what_?  */
+   if (GET_MODE_CLASS (mode) != MODE_INT
+       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
+     abort ();
+ 
    /* Canonicalize BImode to 0 and STORE_FLAG_VALUE.  */
    if (mode == BImode)
      return c & 1 ? STORE_FLAG_VALUE : 0;
*** gcc.orig/gcc/combine.c	Fri Aug 16 12:12:17 2002
--- gcc/gcc/combine.c	Fri Aug 16 12:20:23 2002
*************** expand_compound_operation (x)
*** 5634,5639 ****
--- 5634,5646 ----
        if (GET_MODE_SIZE (GET_MODE (XEXP (x, 0))) > UNITS_PER_WORD)
  	return x;
  
+       /* Reject MODEs that aren't MODE_INT or MODE_PARTIAL_INT because
+          turning vector or complex modes into shifts causes problems.  */
+ 
+       if (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_INT
+           && GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_PARTIAL_INT)
+         return x;
+ 
        len = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)));
        /* If the inner object has VOIDmode (the only way this can happen
  	 is if it is an ASM_OPERANDS), we can't do anything since we don't
*************** expand_compound_operation (x)
*** 5655,5660 ****
--- 5662,5674 ----
  	  || GET_MODE (XEXP (x, 0)) == VOIDmode)
  	return x;
  
+       /* Reject MODEs that aren't MODE_INT or MODE_PARTIAL_INT because
+          turning vector or complex modes into shifts causes problems.  */
+ 
+       if (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_INT
+           && GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_PARTIAL_INT)
+         return x;
+ 
        len = INTVAL (XEXP (x, 1));
        pos = INTVAL (XEXP (x, 2));
  
*************** expand_field_assignment (x)
*** 5862,5873 ****
  
        compute_mode = GET_MODE (inner);
  
!       /* Don't attempt bitwise arithmetic on non-integral modes.  */
!       if (! INTEGRAL_MODE_P (compute_mode))
  	{
  	  enum machine_mode imode;
  
! 	  /* Something is probably seriously wrong if this matches.  */
  	  if (! FLOAT_MODE_P (compute_mode))
  	    break;
  
--- 5876,5889 ----
  
        compute_mode = GET_MODE (inner);
  
!       /* Don't attempt bitwise arithmetic on non-integer modes.  */
!       if (GET_MODE_CLASS (compute_mode) != MODE_INT
! 	  && GET_MODE_CLASS (compute_mode) != MODE_PARTIAL_INT)
!          
  	{
  	  enum machine_mode imode;
  
! 	  /* Don't try doing anything for Vector or Integer complex types.  */
  	  if (! FLOAT_MODE_P (compute_mode))
  	    break;
  
*************** simplify_comparison (code, pop0, pop1)
*** 10177,10183 ****
  
        /* Get the constant we are comparing against and turn off all bits
  	 not on in our mode.  */
!       const_op = trunc_int_for_mode (INTVAL (op1), mode);
        op1 = GEN_INT (const_op);
  
        /* If we are comparing against a constant power of two and the value
--- 10193,10201 ----
  
        /* Get the constant we are comparing against and turn off all bits
  	 not on in our mode.  */
!       const_op = INTVAL (op1);
!       if (mode != VOIDmode)
! 	const_op = trunc_int_for_mode (const_op, mode);
        op1 = GEN_INT (const_op);
  
        /* If we are comparing against a constant power of two and the value
*** gcc.orig/gcc/recog.c	Fri Aug 16 12:12:21 2002
--- gcc/gcc/recog.c	Fri Aug 16 12:12:55 2002
*************** general_operand (op, mode)
*** 954,959 ****
--- 954,960 ----
      return 0;
  
    if (GET_CODE (op) == CONST_INT
+       && mode != VOIDmode
        && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
      return 0;
  
*************** immediate_operand (op, mode)
*** 1159,1164 ****
--- 1160,1166 ----
      return 0;
  
    if (GET_CODE (op) == CONST_INT
+       && mode != VOIDmode
        && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
      return 0;
  
*************** nonmemory_operand (op, mode)
*** 1241,1246 ****
--- 1243,1249 ----
  	return 0;
  
        if (GET_CODE (op) == CONST_INT
+ 	  && mode != VOIDmode
  	  && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
  	return 0;
  


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