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] Initialize variable in order to survive PGO bootstrap.


Richard Biener <richard.guenther@gmail.com> writes:
> On Fri, Nov 3, 2017 at 9:52 AM, Martin Liška <mliska@suse.cz> wrote:
>> Hi.
>>
>> This is oneliner that fixes PGO bootstrap. I've discussed that with
>> Richi and the core is correct.
>> However we probably don't have an attribute that will ignore the warning?
>
> I think
>
>   wide_int res = res;
>
> might do (untested).
>
>> Only option is to push/pop Wuninitialized warning.
>
> Too ugly...
>
>> Ready for trunk?
>
> Any better idea?  Richard?

It looks like we're deliberately returning an uninitialised value if
there's an overflow, is that right?  If so, how about switching it
so that we return success directly and the value by pointer?
Doing it that way should be more efficient, since I don't think
we'll benefit from NRV optimisation as things stand.

It'd be best to avoid wi::zero (0) since 0-precision values aren't valid.

Thanks,
Richard


2017-11-04  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	* tree-vrp.c (vrp_int_const_binop): Return true on success and
	return the value by pointer.
	(extract_range_from_multiplicative_op_1): Update accordingly.
	Return as soon as an operation fails.

Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c	2017-11-03 12:15:44.102059976 +0000
--- gcc/tree-vrp.c	2017-11-04 18:46:32.512257350 +0000
*************** extract_range_from_ssa_name (value_range
*** 1619,1639 ****
  }
  
  
! /* Wrapper around int_const_binop.  If the operation overflows and
!    overflow is undefined, then adjust the result to be
!    -INF or +INF depending on CODE, VAL1 and VAL2.  Sets *OVERFLOW_P
!    to whether the operation overflowed.  For division by zero
!    the result is indeterminate but *OVERFLOW_P is set.  */
! 
! static wide_int
! vrp_int_const_binop (enum tree_code code, tree val1, tree val2,
! 		     bool *overflow_p)
  {
    bool overflow = false;
    signop sign = TYPE_SIGN (TREE_TYPE (val1));
-   wide_int res;
- 
-   *overflow_p = false;
  
    switch (code)
      {
--- 1619,1638 ----
  }
  
  
! /* Wrapper around int_const_binop.  Return true if we can compute the
!    result; i.e. if the operation doesn't overflow or if the overflow is
!    undefined.  In the latter case (if the operation overflows and
!    overflow is undefined), then adjust the result to be -INF or +INF
!    depending on CODE, VAL1 and VAL2.  Return the value in *RES.
! 
!    Return false for division by zero, for which the result is
!    indeterminate.  */
! 
! static bool
! vrp_int_const_binop (enum tree_code code, tree val1, tree val2, wide_int *res)
  {
    bool overflow = false;
    signop sign = TYPE_SIGN (TREE_TYPE (val1));
  
    switch (code)
      {
*************** vrp_int_const_binop (enum tree_code code
*** 1654,1710 ****
  	  /* It's unclear from the C standard whether shifts can overflow.
  	     The following code ignores overflow; perhaps a C standard
  	     interpretation ruling is needed.  */
! 	  res = wi::rshift (wi::to_wide (val1), wval2, sign);
  	else
! 	  res = wi::lshift (wi::to_wide (val1), wval2);
  	break;
        }
  
      case MULT_EXPR:
!       res = wi::mul (wi::to_wide (val1),
! 		     wi::to_wide (val2), sign, &overflow);
        break;
  
      case TRUNC_DIV_EXPR:
      case EXACT_DIV_EXPR:
        if (val2 == 0)
! 	{
! 	  *overflow_p = true;
! 	  return res;
! 	}
        else
! 	res = wi::div_trunc (wi::to_wide (val1),
! 			     wi::to_wide (val2), sign, &overflow);
        break;
  
      case FLOOR_DIV_EXPR:
        if (val2 == 0)
! 	{
! 	  *overflow_p = true;
! 	  return res;
! 	}
!       res = wi::div_floor (wi::to_wide (val1),
! 			   wi::to_wide (val2), sign, &overflow);
        break;
  
      case CEIL_DIV_EXPR:
        if (val2 == 0)
! 	{
! 	  *overflow_p = true;
! 	  return res;
! 	}
!       res = wi::div_ceil (wi::to_wide (val1),
! 			  wi::to_wide (val2), sign, &overflow);
        break;
  
      case ROUND_DIV_EXPR:
        if (val2 == 0)
! 	{
! 	  *overflow_p = 0;
! 	  return res;
! 	}
!       res = wi::div_round (wi::to_wide (val1),
! 			   wi::to_wide (val2), sign, &overflow);
        break;
  
      default:
--- 1653,1697 ----
  	  /* It's unclear from the C standard whether shifts can overflow.
  	     The following code ignores overflow; perhaps a C standard
  	     interpretation ruling is needed.  */
! 	  *res = wi::rshift (wi::to_wide (val1), wval2, sign);
  	else
! 	  *res = wi::lshift (wi::to_wide (val1), wval2);
  	break;
        }
  
      case MULT_EXPR:
!       *res = wi::mul (wi::to_wide (val1),
! 		      wi::to_wide (val2), sign, &overflow);
        break;
  
      case TRUNC_DIV_EXPR:
      case EXACT_DIV_EXPR:
        if (val2 == 0)
! 	return false;
        else
! 	*res = wi::div_trunc (wi::to_wide (val1),
! 			      wi::to_wide (val2), sign, &overflow);
        break;
  
      case FLOOR_DIV_EXPR:
        if (val2 == 0)
! 	return false;
!       *res = wi::div_floor (wi::to_wide (val1),
! 			    wi::to_wide (val2), sign, &overflow);
        break;
  
      case CEIL_DIV_EXPR:
        if (val2 == 0)
! 	return false;
!       *res = wi::div_ceil (wi::to_wide (val1),
! 			   wi::to_wide (val2), sign, &overflow);
        break;
  
      case ROUND_DIV_EXPR:
        if (val2 == 0)
! 	return false;
!       *res = wi::div_round (wi::to_wide (val1),
! 			    wi::to_wide (val2), sign, &overflow);
        break;
  
      default:
*************** vrp_int_const_binop (enum tree_code code
*** 1747,1762 ****
  	  || code == CEIL_DIV_EXPR
  	  || code == EXACT_DIV_EXPR
  	  || code == ROUND_DIV_EXPR)
! 	return wi::max_value (TYPE_PRECISION (TREE_TYPE (val1)),
  			      TYPE_SIGN (TREE_TYPE (val1)));
        else
! 	return wi::min_value (TYPE_PRECISION (TREE_TYPE (val1)),
  			      TYPE_SIGN (TREE_TYPE (val1)));
      }
  
!   *overflow_p = overflow;
! 
!   return res;
  }
  
  
--- 1734,1748 ----
  	  || code == CEIL_DIV_EXPR
  	  || code == EXACT_DIV_EXPR
  	  || code == ROUND_DIV_EXPR)
! 	*res = wi::max_value (TYPE_PRECISION (TREE_TYPE (val1)),
  			      TYPE_SIGN (TREE_TYPE (val1)));
        else
! 	*res = wi::min_value (TYPE_PRECISION (TREE_TYPE (val1)),
  			      TYPE_SIGN (TREE_TYPE (val1)));
+       return true;
      }
  
!   return !overflow;
  }
  
  
*************** extract_range_from_multiplicative_op_1 (
*** 1852,1858 ****
  {
    enum value_range_type rtype;
    wide_int val, min, max;
-   bool sop;
    tree type;
  
    /* Multiplications, divisions and shifts are a bit tricky to handle,
--- 1838,1843 ----
*************** extract_range_from_multiplicative_op_1 (
*** 1883,1940 ****
    signop sgn = TYPE_SIGN (type);
  
    /* Compute the 4 cross operations and their minimum and maximum value.  */
!   sop = false;
!   val = vrp_int_const_binop (code, vr0->min, vr1->min, &sop);
!   if (! sop)
!     min = max = val;
! 
!   if (vr1->max == vr1->min)
!     ;
!   else if (! sop)
      {
!       val = vrp_int_const_binop (code, vr0->min, vr1->max, &sop);
!       if (! sop)
! 	{
! 	  if (wi::lt_p (val, min, sgn))
! 	    min = val;
! 	  else if (wi::gt_p (val, max, sgn))
! 	    max = val;
! 	}
      }
  
!   if (vr0->max == vr0->min)
!     ;
!   else if (! sop)
      {
!       val = vrp_int_const_binop (code, vr0->max, vr1->min, &sop);
!       if (! sop)
  	{
! 	  if (wi::lt_p (val, min, sgn))
! 	    min = val;
! 	  else if (wi::gt_p (val, max, sgn))
! 	    max = val;
  	}
      }
  
!   if (vr0->min == vr0->max || vr1->min == vr1->max)
!     ;
!   else if (! sop)
      {
!       val = vrp_int_const_binop (code, vr0->max, vr1->max, &sop);
!       if (! sop)
  	{
! 	  if (wi::lt_p (val, min, sgn))
! 	    min = val;
! 	  else if (wi::gt_p (val, max, sgn))
! 	    max = val;
  	}
      }
  
!   /* If either operation overflowed, drop to VARYING.  */
!   if (sop)
      {
!       set_value_range_to_varying (vr);
!       return;
      }
  
    /* If the new range has its limits swapped around (MIN > MAX),
--- 1868,1917 ----
    signop sgn = TYPE_SIGN (type);
  
    /* Compute the 4 cross operations and their minimum and maximum value.  */
!   if (!vrp_int_const_binop (code, vr0->min, vr1->min, &val))
      {
!       set_value_range_to_varying (vr);
!       return;
      }
+   min = max = val;
  
!   if (vr1->max != vr1->min)
      {
!       if (!vrp_int_const_binop (code, vr0->min, vr1->max, &val))
  	{
! 	  set_value_range_to_varying (vr);
! 	  return;
  	}
+       if (wi::lt_p (val, min, sgn))
+ 	min = val;
+       else if (wi::gt_p (val, max, sgn))
+ 	max = val;
      }
  
!   if (vr0->max != vr0->min)
      {
!       if (!vrp_int_const_binop (code, vr0->max, vr1->min, &val))
  	{
! 	  set_value_range_to_varying (vr);
! 	  return;
  	}
+       if (wi::lt_p (val, min, sgn))
+ 	min = val;
+       else if (wi::gt_p (val, max, sgn))
+ 	max = val;
      }
  
!   if (vr0->min != vr0->max && vr1->min != vr1->max)
      {
!       if (!vrp_int_const_binop (code, vr0->max, vr1->max, &val))
! 	{
! 	  set_value_range_to_varying (vr);
! 	  return;
! 	}
!       if (wi::lt_p (val, min, sgn))
! 	min = val;
!       else if (wi::gt_p (val, max, sgn))
! 	max = val;
      }
  
    /* If the new range has its limits swapped around (MIN > MAX),


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