From 6cc3394507a2303a18891d34222c53f679256c37 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Wed, 5 Oct 2022 10:42:07 -0400
Subject: [PATCH 4/4] propagate partial equivs in the cache.
Adjust on-entry cache propagation to look for and propagate both full
and partial equivalences.
gcc/
PR tree-optimization/102540
PR tree-optimization/102872
* gimple-range-cache.cc (ranger_cache::fill_block_cache):
Handle partial equivs.
(ranger_cache::range_from_dom): Cleanup dump output.
gcc/testsuite/
* gcc.dg/pr102540.c: New.
* gcc.dg/pr102872.c: New.
---
gcc/gimple-range-cache.cc | 37 +++++++++++++++++++++++++++------
gcc/testsuite/gcc.dg/pr102540.c | 19 +++++++++++++++++
gcc/testsuite/gcc.dg/pr102872.c | 16 ++++++++++++++
3 files changed, 66 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/pr102540.c
create mode 100644 gcc/testsuite/gcc.dg/pr102872.c
@@ -1189,8 +1189,9 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
{
edge_iterator ei;
edge e;
- Value_Range block_result (TREE_TYPE (name));
- Value_Range undefined (TREE_TYPE (name));
+ tree type = TREE_TYPE (name);
+ Value_Range block_result (type);
+ Value_Range undefined (type);
// At this point we shouldn't be looking at the def, entry or exit block.
gcc_checking_assert (bb != def_bb && bb != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
@@ -1221,10 +1222,16 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
if (m_oracle)
{
tree equiv_name;
- FOR_EACH_EQUIVALENCE (m_oracle, bb, name, equiv_name)
+ relation_kind rel;
+ int prec = TYPE_PRECISION (type);
+ FOR_EACH_PARTIAL_AND_FULL_EQUIV (m_oracle, bb, name, equiv_name, rel)
{
basic_block equiv_bb = gimple_bb (SSA_NAME_DEF_STMT (equiv_name));
+ // Ignore partial equivs that are smaller than this object.
+ if (rel != VREL_EQ && prec > pe_to_bits (rel))
+ continue;
+
// Check if the equiv has any ranges calculated.
if (!m_gori.has_edge_range_p (equiv_name))
continue;
@@ -1234,16 +1241,32 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
(equiv_bb && !dominated_by_p (CDI_DOMINATORS, bb, equiv_bb)))
continue;
+ if (DEBUG_RANGE_CACHE)
+ {
+ if (rel == VREL_EQ)
+ fprintf (dump_file, "Checking Equivalence (");
+ else
+ fprintf (dump_file, "Checking Partial equiv (");
+ print_relation (dump_file, rel);
+ fprintf (dump_file, ") ");
+ print_generic_expr (dump_file, equiv_name, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
Value_Range equiv_range (TREE_TYPE (equiv_name));
if (range_from_dom (equiv_range, equiv_name, bb, RFD_READ_ONLY))
{
+ if (rel != VREL_EQ)
+ range_cast (equiv_range, type);
if (block_result.intersect (equiv_range))
{
if (DEBUG_RANGE_CACHE)
{
- fprintf (dump_file, "Equivalence update! : ");
+ if (rel == VREL_EQ)
+ fprintf (dump_file, "Equivalence update! : ");
+ else
+ fprintf (dump_file, "Partial equiv update! : ");
print_generic_expr (dump_file, equiv_name, TDF_SLIM);
- fprintf (dump_file, "had range : ");
+ fprintf (dump_file, " has range : ");
equiv_range.dump (dump_file);
fprintf (dump_file, " refining range to :");
block_result.dump (dump_file);
@@ -1458,7 +1481,9 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb,
if (DEBUG_RANGE_CACHE)
{
- fprintf (dump_file, "CACHE: BB %d DOM query, found ", start_bb->index);
+ fprintf (dump_file, "CACHE: BB %d DOM query for ", start_bb->index);
+ print_generic_expr (dump_file, name, TDF_SLIM);
+ fprintf (dump_file, ", found ");
r.dump (dump_file);
if (bb)
fprintf (dump_file, " at BB%d\n", bb->index);
new file mode 100644
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-evrp" } */
+
+
+void kill();
+
+static long a;
+static unsigned b;
+int test1 () {
+ long c, e;
+ c = b = a;
+ e = c ? 2 / (c + 1) : 0;
+ if (e && !b)
+ kill ();
+ a = 0;
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
+
new file mode 100644
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void foo(void);
+
+static int a, b;
+int main() {
+ for (; a; ++a) {
+ unsigned short d = a;
+ if (!(b | d) && d)
+ foo();
+ }
+}
+
+/* { dg-final { scan-tree-dump-not "foo" "evrp" } } */
+
--
2.37.3