Once a range becomes constant, make it invariant.
authorAndrew MacLeod <amacleod@redhat.com>
Mon, 17 May 2021 19:53:39 +0000 (15:53 -0400)
committerAndrew MacLeod <amacleod@redhat.com>
Mon, 17 May 2021 22:11:24 +0000 (18:11 -0400)
Once a range is forced to a constant globally, simply make it invariant.
Unify this with the code which makes non-zero pointer ranges invariant.

gcc/
PR tree-optimization/100512
* gimple-range-cache.cc (ranger_cache::set_global_range): Mark const
and non-zero pointer ranges as invariant.
* gimple-range.cc (gimple_ranger::range_of_stmt): Remove pointer
processing from here.

gcc/testsuite/
PR tree-optimization/100512
* gcc.dg/pr100512.c: New.

gcc/gimple-range-cache.cc
gcc/gimple-range.cc
gcc/testsuite/gcc.dg/pr100512.c [new file with mode: 0644]

index 60e5d66..2c922e3 100644 (file)
@@ -703,8 +703,19 @@ ranger_cache::set_global_range (tree name, const irange &r)
 
       propagate_updated_value (name, bb);
     }
-  // Mark the value as up-to-date.
-  m_temporal->set_timestamp (name);
+  // Constants no longer need to tracked.  Any further refinement has to be
+  // undefined. Propagation works better with constants. PR 100512.
+  // Pointers which resolve to non-zero also do not need
+  // tracking in the cache as they will never change.  See PR 98866.
+  // Otherwise mark the value as up-to-date.
+  if (r.singleton_p ()
+      || (POINTER_TYPE_P (TREE_TYPE (name)) && r.nonzero_p ()))
+    {
+      set_range_invariant (name);
+      m_temporal->set_always_current (name);
+    }
+  else
+    m_temporal->set_timestamp (name);
 }
 
 // Register a dependency on DEP to name.  If the timestamp for DEP is ever
index 5b288d8..710bc7f 100644 (file)
@@ -1082,11 +1082,6 @@ gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name)
   r.intersect (tmp);
   m_cache.set_global_range (name, r);
 
-  // Pointers which resolve to non-zero at the defintion point do not need
-  // tracking in the cache as they will never change.  See PR 98866.
-  if (POINTER_TYPE_P (TREE_TYPE (name)) && r.nonzero_p ())
-    m_cache.set_range_invariant (name);
-
   return true;
 }
 
diff --git a/gcc/testsuite/gcc.dg/pr100512.c b/gcc/testsuite/gcc.dg/pr100512.c
new file mode 100644 (file)
index 0000000..70b90e0
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -w" } */
+
+#include <stdint.h>
+int a;
+void b() {
+  int16_t *c;
+  uint16_t d = 2;
+  if (0 == d) {
+    uint64_t e;
+    uint64_t *f = &e;
+    for (;;) {
+      if (e += 0 >= 0)
+        for (;;)
+          ;
+    g:
+      for (; a;) {
+        int16_t i = &d;
+        *c = i && *f;
+      }
+    }
+  }
+  goto g;
+}
+