[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