diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2021-06-01 17:48:30 +0200 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2021-06-03 16:39:33 +0200 |
commit | 160fe6034bd2ca0073a722b6774518bb9ea5ac02 (patch) | |
tree | b46dacb9e3bdf98c420ca1956e85f3daeb35458d /gcc | |
parent | 981d98b883ed521c88c295ed82227c605d82add4 (diff) | |
download | gcc-160fe6034bd2ca0073a722b6774518bb9ea5ac02.zip gcc-160fe6034bd2ca0073a722b6774518bb9ea5ac02.tar.gz gcc-160fe6034bd2ca0073a722b6774518bb9ea5ac02.tar.bz2 |
Use known global ranges in export_global_ranges
This patch modifies export_global_ranges to take into account current
global ranges. It also handles enhances said function to export pointer
global ranges as well.
gcc/ChangeLog:
* gimple-range.cc (gimple_ranger::export_global_ranges): Call
update_global_range.
* value-query.cc (update_global_range): New.
* value-query.h (update_global_range): New.
gcc/testsuite/ChangeLog:
* gcc.dg/pr80776-1.c: XFAIL and document the reason why.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/gimple-range.cc | 26 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr80776-1.c | 12 | ||||
-rw-r--r-- | gcc/value-query.cc | 39 | ||||
-rw-r--r-- | gcc/value-query.h | 1 |
4 files changed, 61 insertions, 17 deletions
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index ed0a0c9..af42620 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -1115,7 +1115,7 @@ gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name) } // This routine will export whatever global ranges are known to GCC -// SSA_RANGE_NAME_INFO fields. +// SSA_RANGE_NAME_INFO and SSA_NAME_PTR_INFO fields. void gimple_ranger::export_global_ranges () @@ -1136,24 +1136,18 @@ gimple_ranger::export_global_ranges () && m_cache.get_global_range (r, name) && !r.varying_p()) { - // Make sure the new range is a subset of the old range. - int_range_max old_range; - old_range = gimple_range_global (name); - old_range.intersect (r); - /* Disable this while we fix tree-ssa/pr61743-2.c. */ - //gcc_checking_assert (old_range == r); - - // WTF? Can't write non-null pointer ranges?? stupid set_range_info! - if (!POINTER_TYPE_P (TREE_TYPE (name)) && !r.undefined_p ()) + bool updated = update_global_range (r, name); + + if (updated && dump_file) { value_range vr = r; - set_range_info (name, vr); - if (dump_file) + print_generic_expr (dump_file, name , TDF_SLIM); + fprintf (dump_file, " --> "); + vr.dump (dump_file); + fprintf (dump_file, "\n"); + int_range_max same = vr; + if (same != r) { - print_generic_expr (dump_file, name , TDF_SLIM); - fprintf (dump_file, " --> "); - vr.dump (dump_file); - fprintf (dump_file, "\n"); fprintf (dump_file, " irange : "); r.dump (dump_file); fprintf (dump_file, "\n"); diff --git a/gcc/testsuite/gcc.dg/pr80776-1.c b/gcc/testsuite/gcc.dg/pr80776-1.c index f3a120b..eca5e80 100644 --- a/gcc/testsuite/gcc.dg/pr80776-1.c +++ b/gcc/testsuite/gcc.dg/pr80776-1.c @@ -17,5 +17,15 @@ Foo (void) __builtin_unreachable (); if (! (0 <= i && i <= 999999)) __builtin_unreachable (); - sprintf (number, "%d", i); /* { dg-bogus "writing" "" } */ + + /* Legacy evrp sets the range of i to [0, MAX] *before* the first conditional, + and to [0,999999] *before* the second conditional. This is because both + evrp and VRP use trickery to set global ranges when this particular use of + a __builtin_unreachable is in play (see uses of + assert_unreachable_fallthru_edge_p). + + Setting these ranges at the definition site, causes VRP to remove the + unreachable code altogether, leaving the following sprintf unguarded. This + causes the bogus warning below. */ + sprintf (number, "%d", i); /* { dg-bogus "writing" "" { xfail *-*-* } } */ } diff --git a/gcc/value-query.cc b/gcc/value-query.cc index f8b457d..070d706 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -224,6 +224,45 @@ get_ssa_name_ptr_info_nonnull (const_tree name) return !pi->pt.null; } +// Update the global range for NAME into the SSA_RANGE_NAME_INFO and +// SSA_NAME_PTR_INFO fields. Return TRUE if the range for NAME was +// updated. + +bool +update_global_range (irange &r, tree name) +{ + tree type = TREE_TYPE (name); + + if (r.undefined_p () || r.varying_p ()) + return false; + + if (INTEGRAL_TYPE_P (type)) + { + // If a global range already exists, incorporate it. + if (SSA_NAME_RANGE_INFO (name)) + { + value_range glob; + get_ssa_name_range_info (glob, name); + r.intersect (glob); + } + if (r.undefined_p ()) + return false; + + value_range vr = r; + set_range_info (name, vr); + return true; + } + else if (POINTER_TYPE_P (type)) + { + if (r.nonzero_p ()) + { + set_ptr_nonnull (name); + return true; + } + } + return false; +} + // Return the legacy global range for NAME if it has one, otherwise // return VARYING. diff --git a/gcc/value-query.h b/gcc/value-query.h index 97da663..d0512e4 100644 --- a/gcc/value-query.h +++ b/gcc/value-query.h @@ -115,5 +115,6 @@ public: extern global_range_query global_ranges; extern value_range gimple_range_global (tree name); +extern bool update_global_range (irange &r, tree name); #endif // GCC_QUERY_H |