]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Range invariant global values are also always current.
authorAndrew MacLeod <amacleod@redhat.com>
Thu, 27 May 2021 15:19:10 +0000 (11:19 -0400)
committerAndrew MacLeod <amacleod@redhat.com>
Tue, 1 Jun 2021 00:49:39 +0000 (20:49 -0400)
when a range evolves to the point where it becomes a constant, it is
marked as invariant.  Rather than marking it as always_current in the
timestamp, give it the correct timestamp and just never flag it as stale.
This will allow other names which use this value to become stale and be
recomputed using the newly invariant value.

gcc/
PR tree-optimization/100774
* gimple-range-cache.cc (ranger_cache::get_non_stale_global_range):
Constant values are also not stale.
(ranger_cache::set_global_range): Range invariant values should also
have the correct timestamp.

gcc/testsuite
PR tree-optimization/100774
* g++.dg/pr100774.C: New.

gcc/gimple-range-cache.cc
gcc/testsuite/g++.dg/pr100774.C [new file with mode: 0644]

index 889cac1ea65d3bced4f1011eb71adadd30e192ca..ef3bc04489114fc761ee576e01ed3bc2279b195a 100644 (file)
@@ -639,7 +639,9 @@ ranger_cache::get_non_stale_global_range (irange &r, tree name)
 {
   if (m_globals.get_global_range (r, name))
     {
-      if (m_temporal->current_p (name, depend1 (name), depend2 (name)))
+      // Use this value if the range is constant or current.
+      if (r.singleton_p ()
+         || m_temporal->current_p (name, depend1 (name), depend2 (name)))
        return true;
     }
   else
@@ -674,15 +676,13 @@ ranger_cache::set_global_range (tree name, const irange &r)
   // 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.
+  // Timestamp must always be updated, or dependent calculations may
+  // not include this latest value. PR 100774.
+
   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);
+    set_range_invariant (name);
+  m_temporal->set_timestamp (name);
 }
 
 // Push a request for a new lookup in block BB of name.  Return true if
diff --git a/gcc/testsuite/g++.dg/pr100774.C b/gcc/testsuite/g++.dg/pr100774.C
new file mode 100644 (file)
index 0000000..345fcfa
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-forwprop --param=evrp-mode=ranger -fcompare-debug  " } */
+
+extern void __attribute__((noreturn)) error();
+
+int x;
+
+static inline int bar(void) {
+  char n = 1;
+  int i = x & 1U << n - 1;
+  return i;
+}
+
+void foo()
+{
+  int a = bar();
+  for (;;) {
+    bool b;
+    int d = a;
+    b = a < 2;
+    if (!b)
+      error();
+  }
+}