From 3232f0521cda16efeff012f65bc4d0b15d02a7e2 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 6 Nov 2017 08:59:09 +0000 Subject: [PATCH] Rework vrp_int_const_binop interface ...to avoid a warning about uninitialised wide_ints. 2017-11-06 Richard Sandiford 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. From-SVN: r254436 --- gcc/ChangeLog | 7 +++ gcc/tree-vrp.c | 143 +++++++++++++++++++++---------------------------- 2 files changed, 67 insertions(+), 83 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e6e298a1cbd..5556e296bd6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-11-06 Richard Sandiford + + * 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. + 2017-11-05 Tom de Vries PR other/82784 diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 541c5c4eaf9..2b7d9622f69 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1602,21 +1602,20 @@ extract_range_from_ssa_name (value_range *vr, tree var) } -/* 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. */ +/* 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. -static wide_int -vrp_int_const_binop (enum tree_code code, tree val1, tree val2, - bool *overflow_p) + 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)); - wide_int res; - - *overflow_p = false; switch (code) { @@ -1637,57 +1636,45 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2, /* 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); + *res = wi::rshift (wi::to_wide (val1), wval2, sign); else - res = wi::lshift (wi::to_wide (val1), wval2); + *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); + *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; - } + return false; else - res = wi::div_trunc (wi::to_wide (val1), - wi::to_wide (val2), sign, &overflow); + *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); + return false; + *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); + return false; + *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); + return false; + *res = wi::div_round (wi::to_wide (val1), + wi::to_wide (val2), sign, &overflow); break; default: @@ -1730,16 +1717,15 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2, || code == CEIL_DIV_EXPR || code == EXACT_DIV_EXPR || code == ROUND_DIV_EXPR) - return wi::max_value (TYPE_PRECISION (TREE_TYPE (val1)), + *res = wi::max_value (TYPE_PRECISION (TREE_TYPE (val1)), TYPE_SIGN (TREE_TYPE (val1))); else - return wi::min_value (TYPE_PRECISION (TREE_TYPE (val1)), + *res = wi::min_value (TYPE_PRECISION (TREE_TYPE (val1)), TYPE_SIGN (TREE_TYPE (val1))); + return true; } - *overflow_p = overflow; - - return res; + return !overflow; } @@ -1835,7 +1821,6 @@ extract_range_from_multiplicative_op_1 (value_range *vr, { enum value_range_type rtype; wide_int val, min, max; - bool sop; tree type; /* Multiplications, divisions and shifts are a bit tricky to handle, @@ -1866,58 +1851,50 @@ extract_range_from_multiplicative_op_1 (value_range *vr, 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) + if (!vrp_int_const_binop (code, vr0->min, vr1->min, &val)) { - 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; - } + set_value_range_to_varying (vr); + return; } + min = max = val; - if (vr0->max == vr0->min) - ; - else if (! sop) + if (vr1->max != vr1->min) { - val = vrp_int_const_binop (code, vr0->max, vr1->min, &sop); - if (! sop) + if (!vrp_int_const_binop (code, vr0->min, vr1->max, &val)) { - if (wi::lt_p (val, min, sgn)) - min = val; - else if (wi::gt_p (val, max, sgn)) - 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->min == vr0->max || vr1->min == vr1->max) - ; - else if (! sop) + if (vr0->max != vr0->min) { - val = vrp_int_const_binop (code, vr0->max, vr1->max, &sop); - if (! sop) + if (!vrp_int_const_binop (code, vr0->max, vr1->min, &val)) { - if (wi::lt_p (val, min, sgn)) - min = val; - else if (wi::gt_p (val, max, sgn)) - 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 either operation overflowed, drop to VARYING. */ - if (sop) + if (vr0->min != vr0->max && vr1->min != vr1->max) { - set_value_range_to_varying (vr); - return; + 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), -- 2.30.2