This is the mail archive of the gcc@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: some integer undefined behaviors in gcc


> I ran gcc 162830 on x86 under a tool that checks for integer undefined
> behaviors.  The attached error messages show up when running "make
> check" and when recompiling gcc.
>
> Each line in the attachment is an error message giving the problematic
> operator, its srcloc, the types of its operands, and examples of
> offending values.

Thanks for doing this.  I've attached a patch that should fix rtlanal.c.

> Let me know if more detail is needed or if it would be better for me to
> file all 71 bug reports.

I think the messages are clear enough.  You should probably wait a few days to 
let people comment and/or fix, and then file PRs.  1 per file seems to be the 
right granularity.


	* rtlanal.c (nonzero_bits1): Use unsigned HOST_WIDE_INT in all mask
	computations.  Fix formatting issues.


-- 
Eric Botcazou
Index: rtlanal.c
===================================================================
--- rtlanal.c	(revision 162622)
+++ rtlanal.c	(working copy)
@@ -3803,12 +3803,14 @@ nonzero_bits1 (const_rtx x, enum machine
     case CONST_INT:
 #ifdef SHORT_IMMEDIATES_SIGN_EXTEND
       /* If X is negative in MODE, sign-extend the value.  */
-      if (INTVAL (x) > 0 && mode_width < BITS_PER_WORD
-	  && 0 != (INTVAL (x) & ((HOST_WIDE_INT) 1 << (mode_width - 1))))
-	return (INTVAL (x) | ((HOST_WIDE_INT) (-1) << mode_width));
+      if (INTVAL (x) > 0
+	  && mode_width < BITS_PER_WORD
+	  && (UINTVAL (x) & ((unsigned HOST_WIDE_INT) 1 << (mode_width - 1)))
+	     != 0)
+	return UINTVAL (x) | ((unsigned HOST_WIDE_INT) (-1) << mode_width);
 #endif
 
-      return INTVAL (x);
+      return UINTVAL (x);
 
     case MEM:
 #ifdef LOAD_EXTEND_OP
@@ -3885,7 +3887,7 @@ nonzero_bits1 (const_rtx x, enum machine
 	{
 	  inner_nz &= GET_MODE_MASK (GET_MODE (XEXP (x, 0)));
 	  if (inner_nz
-	      & (((HOST_WIDE_INT) 1
+	      & (((unsigned HOST_WIDE_INT) 1
 		  << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1))))
 	    inner_nz |= (GET_MODE_MASK (mode)
 			 & ~GET_MODE_MASK (GET_MODE (XEXP (x, 0))));
@@ -3904,9 +3906,9 @@ nonzero_bits1 (const_rtx x, enum machine
     case XOR:   case IOR:
     case UMIN:  case UMAX:  case SMIN:  case SMAX:
       {
-	unsigned HOST_WIDE_INT nonzero0 =
-	  cached_nonzero_bits (XEXP (x, 0), mode,
-			       known_x, known_mode, known_ret);
+	unsigned HOST_WIDE_INT nonzero0
+	   = cached_nonzero_bits (XEXP (x, 0), mode,
+				  known_x, known_mode, known_ret);
 
 	/* Don't call nonzero_bits for the second time if it cannot change
 	   anything.  */
@@ -3926,21 +3928,21 @@ nonzero_bits1 (const_rtx x, enum machine
 	 computing the width (position of the highest-order nonzero bit)
 	 and the number of low-order zero bits for each value.  */
       {
-	unsigned HOST_WIDE_INT nz0 =
-	  cached_nonzero_bits (XEXP (x, 0), mode,
-			       known_x, known_mode, known_ret);
-	unsigned HOST_WIDE_INT nz1 =
-	  cached_nonzero_bits (XEXP (x, 1), mode,
-			       known_x, known_mode, known_ret);
+	unsigned HOST_WIDE_INT nz0
+	  = cached_nonzero_bits (XEXP (x, 0), mode,
+				 known_x, known_mode, known_ret);
+	unsigned HOST_WIDE_INT nz1
+	  = cached_nonzero_bits (XEXP (x, 1), mode,
+				 known_x, known_mode, known_ret);
 	int sign_index = GET_MODE_BITSIZE (GET_MODE (x)) - 1;
 	int width0 = floor_log2 (nz0) + 1;
 	int width1 = floor_log2 (nz1) + 1;
 	int low0 = floor_log2 (nz0 & -nz0);
 	int low1 = floor_log2 (nz1 & -nz1);
-	HOST_WIDE_INT op0_maybe_minusp
-	  = (nz0 & ((HOST_WIDE_INT) 1 << sign_index));
-	HOST_WIDE_INT op1_maybe_minusp
-	  = (nz1 & ((HOST_WIDE_INT) 1 << sign_index));
+	unsigned HOST_WIDE_INT op0_maybe_minusp
+	  = nz0 & ((unsigned HOST_WIDE_INT) 1 << sign_index);
+	unsigned HOST_WIDE_INT op1_maybe_minusp
+	  = nz1 & ((unsigned HOST_WIDE_INT) 1 << sign_index);
 	unsigned int result_width = mode_width;
 	int result_low = 0;
 
@@ -3960,7 +3962,7 @@ nonzero_bits1 (const_rtx x, enum machine
 	  case DIV:
 	    if (width1 == 0)
 	      break;
-	    if (! op0_maybe_minusp && ! op1_maybe_minusp)
+	    if (!op0_maybe_minusp && !op1_maybe_minusp)
 	      result_width = width0;
 	    break;
 	  case UDIV:
@@ -3971,7 +3973,7 @@ nonzero_bits1 (const_rtx x, enum machine
 	  case MOD:
 	    if (width1 == 0)
 	      break;
-	    if (! op0_maybe_minusp && ! op1_maybe_minusp)
+	    if (!op0_maybe_minusp && !op1_maybe_minusp)
 	      result_width = MIN (width0, width1);
 	    result_low = MIN (low0, low1);
 	    break;
@@ -3986,10 +3988,10 @@ nonzero_bits1 (const_rtx x, enum machine
 	  }
 
 	if (result_width < mode_width)
-	  nonzero &= ((HOST_WIDE_INT) 1 << result_width) - 1;
+	  nonzero &= ((unsigned HOST_WIDE_INT) 1 << result_width) - 1;
 
 	if (result_low > 0)
-	  nonzero &= ~(((HOST_WIDE_INT) 1 << result_low) - 1);
+	  nonzero &= ~(((unsigned HOST_WIDE_INT) 1 << result_low) - 1);
 
 #ifdef POINTERS_EXTEND_UNSIGNED
 	/* If pointers extend unsigned and this is an addition or subtraction
@@ -4010,7 +4012,7 @@ nonzero_bits1 (const_rtx x, enum machine
     case ZERO_EXTRACT:
       if (CONST_INT_P (XEXP (x, 1))
 	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
-	nonzero &= ((HOST_WIDE_INT) 1 << INTVAL (XEXP (x, 1))) - 1;
+	nonzero &= ((unsigned HOST_WIDE_INT) 1 << INTVAL (XEXP (x, 1))) - 1;
       break;
 
     case SUBREG:
@@ -4075,9 +4077,9 @@ nonzero_bits1 (const_rtx x, enum machine
 	  unsigned int width = GET_MODE_BITSIZE (inner_mode);
 	  int count = INTVAL (XEXP (x, 1));
 	  unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (inner_mode);
-	  unsigned HOST_WIDE_INT op_nonzero =
-	    cached_nonzero_bits (XEXP (x, 0), mode,
-				 known_x, known_mode, known_ret);
+	  unsigned HOST_WIDE_INT op_nonzero
+	    = cached_nonzero_bits (XEXP (x, 0), mode,
+				   known_x, known_mode, known_ret);
 	  unsigned HOST_WIDE_INT inner = op_nonzero & mode_mask;
 	  unsigned HOST_WIDE_INT outer = 0;
 
@@ -4093,8 +4095,9 @@ nonzero_bits1 (const_rtx x, enum machine
 	      /* If the sign bit may have been nonzero before the shift, we
 		 need to mark all the places it could have been copied to
 		 by the shift as possibly nonzero.  */
-	      if (inner & ((HOST_WIDE_INT) 1 << (width - 1 - count)))
-		inner |= (((HOST_WIDE_INT) 1 << count) - 1) << (width - count);
+	      if (inner & ((unsigned HOST_WIDE_INT) 1 << (width - 1 - count)))
+		inner |= (((unsigned HOST_WIDE_INT) 1 << count) - 1)
+			   << (width - count);
 	    }
 	  else if (code == ASHIFT)
 	    inner <<= count;
@@ -4109,14 +4112,15 @@ nonzero_bits1 (const_rtx x, enum machine
     case FFS:
     case POPCOUNT:
       /* This is at most the number of bits in the mode.  */
-      nonzero = ((HOST_WIDE_INT) 2 << (floor_log2 (mode_width))) - 1;
+      nonzero = ((unsigned HOST_WIDE_INT) 2 << (floor_log2 (mode_width))) - 1;
       break;
 
     case CLZ:
       /* If CLZ has a known value at zero, then the nonzero bits are
 	 that value, plus the number of bits in the mode minus one.  */
       if (CLZ_DEFINED_VALUE_AT_ZERO (mode, nonzero))
-	nonzero |= ((HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1;
+	nonzero
+	  |= ((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1;
       else
 	nonzero = -1;
       break;
@@ -4125,7 +4129,8 @@ nonzero_bits1 (const_rtx x, enum machine
       /* If CTZ has a known value at zero, then the nonzero bits are
 	 that value, plus the number of bits in the mode minus one.  */
       if (CTZ_DEFINED_VALUE_AT_ZERO (mode, nonzero))
-	nonzero |= ((HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1;
+	nonzero
+	  |= ((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1;
       else
 	nonzero = -1;
       break;
@@ -4136,9 +4141,9 @@ nonzero_bits1 (const_rtx x, enum machine
 
     case IF_THEN_ELSE:
       {
-	unsigned HOST_WIDE_INT nonzero_true =
-	  cached_nonzero_bits (XEXP (x, 1), mode,
-			       known_x, known_mode, known_ret);
+	unsigned HOST_WIDE_INT nonzero_true
+	  = cached_nonzero_bits (XEXP (x, 1), mode,
+				 known_x, known_mode, known_ret);
 
 	/* Don't call nonzero_bits for the second time if it cannot change
 	   anything.  */

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