diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2021-11-04 11:07:28 -0400 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2021-11-04 13:15:36 -0400 |
commit | 004afb984beb6efbe25f44a5857b1c27ebc2ec82 (patch) | |
tree | 6f9c5a694d125164cad695d5ef02fcd44d551fdb | |
parent | 1ece90ffa9ce63b416296bd662b8117d9b538913 (diff) | |
download | gcc-004afb984beb6efbe25f44a5857b1c27ebc2ec82.zip gcc-004afb984beb6efbe25f44a5857b1c27ebc2ec82.tar.gz gcc-004afb984beb6efbe25f44a5857b1c27ebc2ec82.tar.bz2 |
Treat undefined operands as varying in GORI.
If the LHS is UNDEFINED simply stop calculating. Treat op1 and op2
as VARYING if they are UNDEFINED.
PR tree-optimization/103079
gcc/
* gimple-range-gori.cc (gimple_range_calc_op1): Treat undefined as
varying.
(gimple_range_calc_op2): Ditto.
gcc/testsuite/
* gcc.dg/pr103079.c: New.
-rw-r--r-- | gcc/gimple-range-gori.cc | 40 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr103079.c | 20 |
2 files changed, 45 insertions, 15 deletions
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index 4e45c59..2e58c23 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -37,16 +37,13 @@ bool gimple_range_calc_op1 (irange &r, const gimple *stmt, const irange &lhs_range) { gcc_checking_assert (gimple_num_ops (stmt) < 3); - - // An empty range is viral. - tree type = TREE_TYPE (gimple_range_operand1 (stmt)); + // Give up on empty ranges. if (lhs_range.undefined_p ()) - { - r.set_undefined (); - return true; - } + return false; + // Unary operations require the type of the first operand in the // second range position. + tree type = TREE_TYPE (gimple_range_operand1 (stmt)); int_range<2> type_range (type); return gimple_range_handler (stmt)->op1_range (r, type, lhs_range, type_range); @@ -61,15 +58,23 @@ bool gimple_range_calc_op1 (irange &r, const gimple *stmt, const irange &lhs_range, const irange &op2_range) { + // Give up on empty ranges. + if (lhs_range.undefined_p ()) + return false; + // Unary operation are allowed to pass a range in for second operand // as there are often additional restrictions beyond the type which // can be imposed. See operator_cast::op1_range(). tree type = TREE_TYPE (gimple_range_operand1 (stmt)); - // An empty range is viral. - if (op2_range.undefined_p () || lhs_range.undefined_p ()) + // If op2 is undefined, solve as if it is varying. + if (op2_range.undefined_p ()) { - r.set_undefined (); - return true; + // This is sometimes invoked on single operand stmts. + if (gimple_num_ops (stmt) < 3) + return false; + int_range<2> trange (TREE_TYPE (gimple_range_operand2 (stmt))); + return gimple_range_handler (stmt)->op1_range (r, type, lhs_range, + trange); } return gimple_range_handler (stmt)->op1_range (r, type, lhs_range, op2_range); @@ -84,12 +89,17 @@ bool gimple_range_calc_op2 (irange &r, const gimple *stmt, const irange &lhs_range, const irange &op1_range) { + // Give up on empty ranges. + if (lhs_range.undefined_p ()) + return false; + tree type = TREE_TYPE (gimple_range_operand2 (stmt)); - // An empty range is viral. - if (op1_range.undefined_p () || lhs_range.undefined_p ()) + // If op1 is undefined, solve as if it is varying. + if (op1_range.undefined_p ()) { - r.set_undefined (); - return true; + int_range<2> trange (TREE_TYPE (gimple_range_operand1 (stmt))); + return gimple_range_handler (stmt)->op2_range (r, type, lhs_range, + trange); } return gimple_range_handler (stmt)->op2_range (r, type, lhs_range, op1_range); diff --git a/gcc/testsuite/gcc.dg/pr103079.c b/gcc/testsuite/gcc.dg/pr103079.c new file mode 100644 index 0000000..7f6632f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr103079.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -fdump-tree-vrp2" } */ + +int a, b = -2; +int main() { + int d = 0; + int t; + if (b) + goto t1; + if (t) { +t1: + if (!a) + d = b; + while (d > -1) + ; + } + return 0; +} +/* { dg-final { scan-tree-dump "PHI" "vrp2" } } */ + |