From 22984f3f090921b5ac80ec0057f6754ec458e97e Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Thu, 5 Nov 2020 13:59:45 -0500 Subject: [PATCH] Pass multi-range from range_query::value_* routines fix range-ops equal/not_equal to not reuse the result range as intermediary. value_query::value routines should pasa multi-range in as some other rangeop routines build into this result, so we may need better precision. gcc/ PR tree-optimization/97725 * range-op.cc (operator_equal::fold_range): Use new tmp value. (operator_not_equal::fold_range): Ditto. * value-query.cc (range_query::value_of_expr): Use int_range_max not a value_range. (range_query::value_on_edge): Ditto. (range_query::value_of_stmt): Ditto. gcc/testsuite/ * gcc.dg/pr97725.c: New. --- gcc/range-op.cc | 12 ++++++------ gcc/testsuite/gcc.dg/pr97725.c | 28 ++++++++++++++++++++++++++++ gcc/value-query.cc | 6 +++--- 3 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr97725.c diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 74ab2e57fde..f38f02e8d27 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -428,9 +428,9 @@ operator_equal::fold_range (irange &r, tree type, { // If ranges do not intersect, we know the range is not equal, // otherwise we don't know anything for sure. - r = op1; - r.intersect (op2); - if (r.undefined_p ()) + int_range_max tmp = op1; + tmp.intersect (op2); + if (tmp.undefined_p ()) r = range_false (type); else r = range_true_and_false (type); @@ -513,9 +513,9 @@ operator_not_equal::fold_range (irange &r, tree type, { // If ranges do not intersect, we know the range is not equal, // otherwise we don't know anything for sure. - r = op1; - r.intersect (op2); - if (r.undefined_p ()) + int_range_max tmp = op1; + tmp.intersect (op2); + if (tmp.undefined_p ()) r = range_true (type); else r = range_true_and_false (type); diff --git a/gcc/testsuite/gcc.dg/pr97725.c b/gcc/testsuite/gcc.dg/pr97725.c new file mode 100644 index 00000000000..2fcb12cc301 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr97725.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int a; +unsigned b; + +int main() { + if (a) { + goto L1; + while (1) + while (1) { + long e = -1L, g; + int f, h, i; + L1: + a = f; + L2: + g = e; + f = h || g; + e = ~(f & b); + if (i || g < -1L) { + ~(g || 0); + break; + } + goto L2; + } + } + return 0; +} diff --git a/gcc/value-query.cc b/gcc/value-query.cc index 23ba48d73a7..f9a948f3c6c 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -78,7 +78,7 @@ tree range_query::value_of_expr (tree name, gimple *stmt) { tree t; - value_range r; + int_range_max r; if (!irange::supports_type_p (TREE_TYPE (name))) return NULL_TREE; @@ -99,7 +99,7 @@ tree range_query::value_on_edge (edge e, tree name) { tree t; - value_range r; + int_range_max r; if (!irange::supports_type_p (TREE_TYPE (name))) return NULL_TREE; @@ -120,7 +120,7 @@ tree range_query::value_of_stmt (gimple *stmt, tree name) { tree t; - value_range r; + int_range_max r; if (!name) name = gimple_get_lhs (stmt); -- 2.30.2