On November 4, 2017 7:53:12 PM GMT+01:00, Richard Sandiford <richard.sandif...@linaro.org> wrote: >Richard Biener <richard.guent...@gmail.com> writes: >> On Fri, Nov 3, 2017 at 9:52 AM, Martin Liška <mli...@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.sandif...@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),