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]

[PATCH] Remove VRPs use of TYPE_MIN/MAX_VALUE


The middle-end treats conversions between integral types that differ
in TYPE_MIN/MAX_VALUE but not in TYPE_PRECISION or signedness as useless.
This is inconsistent with VRP extracting range information from such
types (and it is not clear how NOP conversions behave here anyway).

The following patch thus simply removes VRPs looking at TYPE_MIN/MAX_VALUE
in favor of using a canonical min/max value based on signedness and
precision.  This exposes a latent bug in upper_bound_in_type and
lower_bound_in_type which do not properly sign-extend sizetype constants.

This makes PR33738 and its testcase moot, thus the patch removes it.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Richard.

2011-04-11  Richard Guenther  <rguenther@suse.de>

	* tree.c (upper_bound_in_type): Properly create canonicalized
	constants.
	(lower_bound_in_type): Likewise.
	* tree-vrp.c (vrp_val_max): Use upper_bound_in_type.
	(vrp_val_min): Use lower_bound_in_type.
	(set_value_range_to_nonnegative): Use vrp_val_min and vrp_val_max
	where appropriate.
	(extract_range_from_assert): Likewise.
	(vrp_int_const_binop): Likewise.
	(extract_range_from_unary_expr): Likewise.
	(adjust_range_with_scev): Likewise.
	(extract_code_and_val_from_cond_with_ops): Likewise.
	(vrp_visit_phi_node): Likewise.
	(test_for_singularity): Likewise.

	* g++.dg/warn/pr33738.C: Remove.

Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c	(revision 172252)
--- gcc/tree-vrp.c	(working copy)
*************** static VEC (switch_update, heap) *to_upd
*** 161,170 ****
  static inline tree
  vrp_val_max (const_tree type)
  {
!   if (!INTEGRAL_TYPE_P (type))
!     return NULL_TREE;
  
!   return TYPE_MAX_VALUE (type);
  }
  
  /* Return the minimum value for TYPE.  */
--- 161,170 ----
  static inline tree
  vrp_val_max (const_tree type)
  {
!   if (INTEGRAL_TYPE_P (type))
!     return upper_bound_in_type (CONST_CAST_TREE (type), CONST_CAST_TREE (type));
  
!   return NULL_TREE;
  }
  
  /* Return the minimum value for TYPE.  */
*************** vrp_val_max (const_tree type)
*** 172,181 ****
  static inline tree
  vrp_val_min (const_tree type)
  {
!   if (!INTEGRAL_TYPE_P (type))
!     return NULL_TREE;
  
!   return TYPE_MIN_VALUE (type);
  }
  
  /* Return whether VAL is equal to the maximum value of its type.  This
--- 172,181 ----
  static inline tree
  vrp_val_min (const_tree type)
  {
!   if (INTEGRAL_TYPE_P (type))
!     return lower_bound_in_type (CONST_CAST_TREE (type), CONST_CAST_TREE (type));
  
!   return NULL_TREE;
  }
  
  /* Return whether VAL is equal to the maximum value of its type.  This
*************** set_value_range_to_nonnegative (value_ra
*** 565,571 ****
    set_value_range (vr, VR_RANGE, zero,
  		   (overflow_infinity
  		    ? positive_overflow_infinity (type)
! 		    : TYPE_MAX_VALUE (type)),
  		   vr->equiv);
  }
  
--- 565,571 ----
    set_value_range (vr, VR_RANGE, zero,
  		   (overflow_infinity
  		    ? positive_overflow_infinity (type)
! 		    : vrp_val_max (type)),
  		   vr->equiv);
  }
  
*************** extract_range_from_assert (value_range_t
*** 1627,1633 ****
      }
    else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
      {
!       min = TYPE_MIN_VALUE (type);
  
        if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
  	max = limit;
--- 1627,1633 ----
      }
    else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
      {
!       min = vrp_val_min (type);
  
        if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
  	max = limit;
*************** extract_range_from_assert (value_range_t
*** 1662,1668 ****
      }
    else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
      {
!       max = TYPE_MAX_VALUE (type);
  
        if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
  	min = limit;
--- 1662,1668 ----
      }
    else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
      {
!       max = vrp_val_max (type);
  
        if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
  	min = limit;
*************** vrp_int_const_binop (enum tree_code code
*** 2079,2089 ****
  	  || code == ROUND_DIV_EXPR)
  	return (needs_overflow_infinity (TREE_TYPE (res))
  		? positive_overflow_infinity (TREE_TYPE (res))
! 		: TYPE_MAX_VALUE (TREE_TYPE (res)));
        else
  	return (needs_overflow_infinity (TREE_TYPE (res))
  		? negative_overflow_infinity (TREE_TYPE (res))
! 		: TYPE_MIN_VALUE (TREE_TYPE (res)));
      }
  
    return res;
--- 2079,2089 ----
  	  || code == ROUND_DIV_EXPR)
  	return (needs_overflow_infinity (TREE_TYPE (res))
  		? positive_overflow_infinity (TREE_TYPE (res))
! 		: vrp_val_max (TREE_TYPE (res)));
        else
  	return (needs_overflow_infinity (TREE_TYPE (res))
  		? negative_overflow_infinity (TREE_TYPE (res))
! 		: vrp_val_min (TREE_TYPE (res)));
      }
  
    return res;
*************** extract_range_from_unary_expr (value_ran
*** 2878,2885 ****
  	  && TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type))
  	{
  	  vr0.type = VR_RANGE;
! 	  vr0.min = TYPE_MIN_VALUE (inner_type);
! 	  vr0.max = TYPE_MAX_VALUE (inner_type);
  	}
  
        /* If VR0 is a constant range or anti-range and the conversion is
--- 2878,2885 ----
  	  && TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type))
  	{
  	  vr0.type = VR_RANGE;
! 	  vr0.min = vrp_val_min (inner_type);
! 	  vr0.max = vrp_val_max (inner_type);
  	}
  
        /* If VR0 is a constant range or anti-range and the conversion is
*************** extract_range_from_unary_expr (value_ran
*** 2964,2970 ****
  	    }
  	}
        else
! 	min = TYPE_MIN_VALUE (type);
  
        if (is_positive_overflow_infinity (vr0.min))
  	max = negative_overflow_infinity (type);
--- 2964,2970 ----
  	    }
  	}
        else
! 	min = vrp_val_min (type);
  
        if (is_positive_overflow_infinity (vr0.min))
  	max = negative_overflow_infinity (type);
*************** extract_range_from_unary_expr (value_ran
*** 2983,2989 ****
  	    }
  	}
        else
! 	max = TYPE_MIN_VALUE (type);
      }
    else if (code == NEGATE_EXPR
  	   && TYPE_UNSIGNED (type))
--- 2983,2989 ----
  	    }
  	}
        else
! 	max = vrp_val_min (type);
      }
    else if (code == NEGATE_EXPR
  	   && TYPE_UNSIGNED (type))
*************** extract_range_from_unary_expr (value_ran
*** 3025,3031 ****
        else if (!vrp_val_is_min (vr0.min))
  	min = fold_unary_to_constant (code, type, vr0.min);
        else if (!needs_overflow_infinity (type))
! 	min = TYPE_MAX_VALUE (type);
        else if (supports_overflow_infinity (type))
  	min = positive_overflow_infinity (type);
        else
--- 3025,3031 ----
        else if (!vrp_val_is_min (vr0.min))
  	min = fold_unary_to_constant (code, type, vr0.min);
        else if (!needs_overflow_infinity (type))
! 	min = vrp_val_max (type);
        else if (supports_overflow_infinity (type))
  	min = positive_overflow_infinity (type);
        else
*************** extract_range_from_unary_expr (value_ran
*** 3039,3045 ****
        else if (!vrp_val_is_min (vr0.max))
  	max = fold_unary_to_constant (code, type, vr0.max);
        else if (!needs_overflow_infinity (type))
! 	max = TYPE_MAX_VALUE (type);
        else if (supports_overflow_infinity (type)
  	       /* We shouldn't generate [+INF, +INF] as set_value_range
  		  doesn't like this and ICEs.  */
--- 3039,3045 ----
        else if (!vrp_val_is_min (vr0.max))
  	max = fold_unary_to_constant (code, type, vr0.max);
        else if (!needs_overflow_infinity (type))
! 	max = vrp_val_max (type);
        else if (supports_overflow_infinity (type)
  	       /* We shouldn't generate [+INF, +INF] as set_value_range
  		  doesn't like this and ICEs.  */
*************** extract_range_from_unary_expr (value_ran
*** 3069,3075 ****
  	         TYPE_MIN_VALUE, remember -TYPE_MIN_VALUE = TYPE_MIN_VALUE.  */
  	      if (TYPE_OVERFLOW_WRAPS (type))
  		{
! 		  tree type_min_value = TYPE_MIN_VALUE (type);
  
  		  min = (vr0.min != type_min_value
  			 ? int_const_binop (PLUS_EXPR, type_min_value,
--- 3069,3075 ----
  	         TYPE_MIN_VALUE, remember -TYPE_MIN_VALUE = TYPE_MIN_VALUE.  */
  	      if (TYPE_OVERFLOW_WRAPS (type))
  		{
! 		  tree type_min_value = vrp_val_min (type);
  
  		  min = (vr0.min != type_min_value
  			 ? int_const_binop (PLUS_EXPR, type_min_value,
*************** extract_range_from_unary_expr (value_ran
*** 3081,3087 ****
  		  if (overflow_infinity_range_p (&vr0))
  		    min = negative_overflow_infinity (type);
  		  else
! 		    min = TYPE_MIN_VALUE (type);
  		}
  	    }
  	  else
--- 3081,3087 ----
  		  if (overflow_infinity_range_p (&vr0))
  		    min = negative_overflow_infinity (type);
  		  else
! 		    min = vrp_val_min (type);
  		}
  	    }
  	  else
*************** extract_range_from_unary_expr (value_ran
*** 3102,3108 ****
  		    }
  		}
  	      else
! 		max = TYPE_MAX_VALUE (type);
  	    }
  	}
  
--- 3102,3108 ----
  		    }
  		}
  	      else
! 		max = vrp_val_max (type);
  	    }
  	}
  
*************** adjust_range_with_scev (value_range_t *v
*** 3386,3396 ****
    if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
      tmin = lower_bound_in_type (type, type);
    else
!     tmin = TYPE_MIN_VALUE (type);
    if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
      tmax = upper_bound_in_type (type, type);
    else
!     tmax = TYPE_MAX_VALUE (type);
  
    /* Try to use estimated number of iterations for the loop to constrain the
       final value in the evolution.
--- 3386,3396 ----
    if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
      tmin = lower_bound_in_type (type, type);
    else
!     tmin = vrp_val_min (type);
    if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
      tmax = upper_bound_in_type (type, type);
    else
!     tmax = vrp_val_max (type);
  
    /* Try to use estimated number of iterations for the loop to constrain the
       final value in the evolution.
*************** extract_code_and_val_from_cond_with_ops
*** 4304,4311 ****
    if ((comp_code == GT_EXPR || comp_code == LT_EXPR)
        && INTEGRAL_TYPE_P (TREE_TYPE (val)))
      {
!       tree min = TYPE_MIN_VALUE (TREE_TYPE (val));
!       tree max = TYPE_MAX_VALUE (TREE_TYPE (val));
  
        if (comp_code == GT_EXPR
  	  && (!max
--- 4304,4311 ----
    if ((comp_code == GT_EXPR || comp_code == LT_EXPR)
        && INTEGRAL_TYPE_P (TREE_TYPE (val)))
      {
!       tree min = vrp_val_min (TREE_TYPE (val));
!       tree max = vrp_val_max (TREE_TYPE (val));
  
        if (comp_code == GT_EXPR
  	  && (!max
*************** vrp_visit_phi_node (gimple phi)
*** 6661,6667 ****
  	{
  	  if (!needs_overflow_infinity (TREE_TYPE (vr_result.min))
  	      || !vrp_var_may_overflow (lhs, phi))
! 	    vr_result.min = TYPE_MIN_VALUE (TREE_TYPE (vr_result.min));
  	  else if (supports_overflow_infinity (TREE_TYPE (vr_result.min)))
  	    vr_result.min =
  		negative_overflow_infinity (TREE_TYPE (vr_result.min));
--- 6661,6667 ----
  	{
  	  if (!needs_overflow_infinity (TREE_TYPE (vr_result.min))
  	      || !vrp_var_may_overflow (lhs, phi))
! 	    vr_result.min = vrp_val_min (TREE_TYPE (vr_result.min));
  	  else if (supports_overflow_infinity (TREE_TYPE (vr_result.min)))
  	    vr_result.min =
  		negative_overflow_infinity (TREE_TYPE (vr_result.min));
*************** vrp_visit_phi_node (gimple phi)
*** 6673,6679 ****
  	{
  	  if (!needs_overflow_infinity (TREE_TYPE (vr_result.max))
  	      || !vrp_var_may_overflow (lhs, phi))
! 	    vr_result.max = TYPE_MAX_VALUE (TREE_TYPE (vr_result.max));
  	  else if (supports_overflow_infinity (TREE_TYPE (vr_result.max)))
  	    vr_result.max =
  		positive_overflow_infinity (TREE_TYPE (vr_result.max));
--- 6673,6679 ----
  	{
  	  if (!needs_overflow_infinity (TREE_TYPE (vr_result.max))
  	      || !vrp_var_may_overflow (lhs, phi))
! 	    vr_result.max = vrp_val_max (TREE_TYPE (vr_result.max));
  	  else if (supports_overflow_infinity (TREE_TYPE (vr_result.max)))
  	    vr_result.max =
  		positive_overflow_infinity (TREE_TYPE (vr_result.max));
*************** test_for_singularity (enum tree_code con
*** 7095,7101 ****
      {
        /* This should not be negative infinity; there is no overflow
  	 here.  */
!       min = TYPE_MIN_VALUE (TREE_TYPE (op0));
  
        max = op1;
        if (cond_code == LT_EXPR && !is_overflow_infinity (max))
--- 7095,7101 ----
      {
        /* This should not be negative infinity; there is no overflow
  	 here.  */
!       min = vrp_val_min (TREE_TYPE (op0));
  
        max = op1;
        if (cond_code == LT_EXPR && !is_overflow_infinity (max))
*************** test_for_singularity (enum tree_code con
*** 7110,7116 ****
      {
        /* This should not be positive infinity; there is no overflow
  	 here.  */
!       max = TYPE_MAX_VALUE (TREE_TYPE (op0));
  
        min = op1;
        if (cond_code == GT_EXPR && !is_overflow_infinity (min))
--- 7110,7116 ----
      {
        /* This should not be positive infinity; there is no overflow
  	 here.  */
!       max = vrp_val_max (TREE_TYPE (op0));
  
        min = op1;
        if (cond_code == GT_EXPR && !is_overflow_infinity (min))
Index: gcc/tree.c
===================================================================
*** gcc/tree.c	(revision 172252)
--- gcc/tree.c	(working copy)
*************** signed_type_for (tree type)
*** 10008,10014 ****
  tree
  upper_bound_in_type (tree outer, tree inner)
  {
!   unsigned HOST_WIDE_INT lo, hi;
    unsigned int det = 0;
    unsigned oprec = TYPE_PRECISION (outer);
    unsigned iprec = TYPE_PRECISION (inner);
--- 10008,10014 ----
  tree
  upper_bound_in_type (tree outer, tree inner)
  {
!   double_int high;
    unsigned int det = 0;
    unsigned oprec = TYPE_PRECISION (outer);
    unsigned iprec = TYPE_PRECISION (inner);
*************** upper_bound_in_type (tree outer, tree in
*** 10055,10072 ****
    /* Compute 2^^prec - 1.  */
    if (prec <= HOST_BITS_PER_WIDE_INT)
      {
!       hi = 0;
!       lo = ((~(unsigned HOST_WIDE_INT) 0)
  	    >> (HOST_BITS_PER_WIDE_INT - prec));
      }
    else
      {
!       hi = ((~(unsigned HOST_WIDE_INT) 0)
  	    >> (2 * HOST_BITS_PER_WIDE_INT - prec));
!       lo = ~(unsigned HOST_WIDE_INT) 0;
      }
  
!   return build_int_cst_wide (outer, lo, hi);
  }
  
  /* Returns the smallest value obtainable by casting something in INNER type to
--- 10055,10072 ----
    /* Compute 2^^prec - 1.  */
    if (prec <= HOST_BITS_PER_WIDE_INT)
      {
!       high.high = 0;
!       high.low = ((~(unsigned HOST_WIDE_INT) 0)
  	    >> (HOST_BITS_PER_WIDE_INT - prec));
      }
    else
      {
!       high.high = ((~(unsigned HOST_WIDE_INT) 0)
  	    >> (2 * HOST_BITS_PER_WIDE_INT - prec));
!       high.low = ~(unsigned HOST_WIDE_INT) 0;
      }
  
!   return double_int_to_tree (outer, high);
  }
  
  /* Returns the smallest value obtainable by casting something in INNER type to
*************** upper_bound_in_type (tree outer, tree in
*** 10075,10081 ****
  tree
  lower_bound_in_type (tree outer, tree inner)
  {
!   unsigned HOST_WIDE_INT lo, hi;
    unsigned oprec = TYPE_PRECISION (outer);
    unsigned iprec = TYPE_PRECISION (inner);
  
--- 10075,10081 ----
  tree
  lower_bound_in_type (tree outer, tree inner)
  {
!   double_int low;
    unsigned oprec = TYPE_PRECISION (outer);
    unsigned iprec = TYPE_PRECISION (inner);
  
*************** lower_bound_in_type (tree outer, tree in
*** 10086,10092 ****
  	 contains all values of INNER type.  In particular, both INNER
  	 and OUTER types have zero in common.  */
        || (oprec > iprec && TYPE_UNSIGNED (inner)))
!     lo = hi = 0;
    else
      {
        /* If we are widening a signed type to another signed type, we
--- 10086,10092 ----
  	 contains all values of INNER type.  In particular, both INNER
  	 and OUTER types have zero in common.  */
        || (oprec > iprec && TYPE_UNSIGNED (inner)))
!     low.low = low.high = 0;
    else
      {
        /* If we are widening a signed type to another signed type, we
*************** lower_bound_in_type (tree outer, tree in
*** 10097,10114 ****
  
        if (prec <= HOST_BITS_PER_WIDE_INT)
  	{
! 	  hi = ~(unsigned HOST_WIDE_INT) 0;
! 	  lo = (~(unsigned HOST_WIDE_INT) 0) << (prec - 1);
  	}
        else
  	{
! 	  hi = ((~(unsigned HOST_WIDE_INT) 0)
  		<< (prec - HOST_BITS_PER_WIDE_INT - 1));
! 	  lo = 0;
  	}
      }
  
!   return build_int_cst_wide (outer, lo, hi);
  }
  
  /* Return nonzero if two operands that are suitable for PHI nodes are
--- 10097,10114 ----
  
        if (prec <= HOST_BITS_PER_WIDE_INT)
  	{
! 	  low.high = ~(unsigned HOST_WIDE_INT) 0;
! 	  low.low = (~(unsigned HOST_WIDE_INT) 0) << (prec - 1);
  	}
        else
  	{
! 	  low.high = ((~(unsigned HOST_WIDE_INT) 0)
  		<< (prec - HOST_BITS_PER_WIDE_INT - 1));
! 	  low.low = 0;
  	}
      }
  
!   return double_int_to_tree (outer, low);
  }
  
  /* Return nonzero if two operands that are suitable for PHI nodes are


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