[PATCH] Initialize variable in order to survive PGO bootstrap.

Richard Biener richard.guenther@gmail.com
Sat Nov 4 20:34:00 GMT 2017


On November 4, 2017 7:53:12 PM GMT+01:00, Richard Sandiford <richard.sandiford@linaro.org> wrote:
>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.

Works for me. 

Thanks, 
Richard. 

>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),



More information about the Gcc-patches mailing list