From: Andrew MacLeod Date: Thu, 4 Nov 2021 15:07:28 +0000 (-0400) Subject: Treat undefined operands as varying in GORI. X-Git-Tag: basepoints/gcc-13~3392 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=004afb984beb6efbe25f44a5857b1c27ebc2ec82;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index 4e45c5938710..2e58c23216b1 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 000000000000..7f6632fc6693 --- /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" } } */ +