When VRP does its dominator walk, any relations which dominate other statements are reflected when fold_range is called.  If however the on-demand engine has looked ahead and resolved back edges, it will sometime spick up the already calculated value that did not have access to a relation.

This patch provides a mechanism for relation registration to indicate that the two operands are "newer" (by giving them a new temporal time stamp), so if they are used in a future calculation is will cause range_of_stmt()  to recognize that the definition is now stale, and recalculate the result... using the now available relation.

Bootstraps on x86_64-pc-linux-gnu with no regressions.  pushed.

Andrew

From 71f41d9b3ac80f428de61486f2cec9604c4d729e Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <[email protected]>
Date: Fri, 14 Nov 2025 15:44:27 -0500
Subject: [PATCH 2/4] Force recalculation when relations are registered.

Whena relation is registered between 2 ssa-names, update their timestamps.
Any calculations using those names will be stale and forced to recalculate.

	* gimple-range-cache.cc (ranger_cache::update_consumers): New.
	* gimple-range-cache.h (update_consumers): New prototype.
	* gimple-range-fold.cc (fur_depend::fur_depend): Add cache ptr.
	(fur_depend::register_relation): call update_consumers.
	* gimple-range-fold.h (fur_depend): Add a cache pointer.
	* gimple-range.cc (gimple_ranger::fold_range_internal): Add cache ptr.
---
 gcc/gimple-range-cache.cc |  9 +++++++++
 gcc/gimple-range-cache.h  |  1 +
 gcc/gimple-range-fold.cc  | 21 +++++++++++++++++----
 gcc/gimple-range-fold.h   |  4 +++-
 gcc/gimple-range.cc       |  2 +-
 5 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index ecf03319cd4..08a953f5012 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -1108,6 +1108,15 @@ ranger_cache::get_global_range (vrange &r, tree name, bool &current_p)
   return had_global;
 }
 
+// Consumers of NAME that have already calculated values should recalculate.
+// Accomplished by updating the timestamp.
+
+void
+ranger_cache::update_consumers (tree name)
+{
+  m_temporal->set_timestamp (name);
+}
+
 //  Set the global range of NAME to R and give it a timestamp.
 
 void
diff --git a/gcc/gimple-range-cache.h b/gcc/gimple-range-cache.h
index 58bf5c57d10..0a49c12edd0 100644
--- a/gcc/gimple-range-cache.h
+++ b/gcc/gimple-range-cache.h
@@ -111,6 +111,7 @@ public:
   bool get_global_range (vrange &r, tree name) const;
   bool get_global_range (vrange &r, tree name, bool &current_p);
   void set_global_range (tree name, const vrange &r, bool changed = true);
+  void update_consumers (tree name);
   range_query &const_query () { return m_globals; }
 
   void propagate_updated_value (tree name, basic_block bb);
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 06c645f3d08..d4481770d76 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -162,11 +162,10 @@ fur_stmt::query_relation (tree op1, tree op2)
   return m_query->relation ().query (m_stmt, op1, op2);
 }
 
-// Instantiate a stmt based fur_source with a GORI object.
+// Instantiate a stmt based fur_source with a GORI object and a ranger cache.
 
-
-fur_depend::fur_depend (gimple *s, range_query *q)
-  : fur_stmt (s, q)
+fur_depend::fur_depend (gimple *s, range_query *q, ranger_cache *c)
+  : fur_stmt (s, q), m_cache (c)
 {
   m_depend_p = true;
 }
@@ -177,6 +176,13 @@ void
 fur_depend::register_relation (gimple *s, relation_kind k, tree op1, tree op2)
 {
   m_query->relation ().record (s, k, op1, op2);
+  // This new relation could cause different calculations, so mark the operands
+  // with a new timestamp, forcing recalculations.
+  if (m_cache)
+    {
+      m_cache->update_consumers (op1);
+      m_cache->update_consumers (op2);
+    }
 }
 
 // Register a relation on an edge if there is an oracle.
@@ -185,6 +191,13 @@ void
 fur_depend::register_relation (edge e, relation_kind k, tree op1, tree op2)
 {
   m_query->relation ().record (e, k, op1, op2);
+  // This new relation could cause different calculations, so mark the operands
+  // with a new timestamp, forcing recalculations.
+  if (m_cache)
+    {
+      m_cache->update_consumers (op1);
+      m_cache->update_consumers (op2);
+    }
 }
 
 // This version of fur_source will pick a range up from a list of ranges
diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
index 826a10fd9e8..760a107821a 100644
--- a/gcc/gimple-range-fold.h
+++ b/gcc/gimple-range-fold.h
@@ -143,11 +143,13 @@ private:
 class fur_depend : public fur_stmt
 {
 public:
-  fur_depend (gimple *s, range_query *q = NULL);
+  fur_depend (gimple *s, range_query *q = NULL, class ranger_cache *c = NULL);
   virtual void register_relation (gimple *stmt, relation_kind k, tree op1,
 				  tree op2) override;
   virtual void register_relation (edge e, relation_kind k, tree op1,
 				  tree op2) override;
+private:
+  ranger_cache *m_cache;
 };
 
 
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index c4093e61d61..f7e0936d391 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -278,7 +278,7 @@ bool
 gimple_ranger::fold_range_internal (vrange &r, gimple *s, tree name)
 {
   fold_using_range f;
-  fur_depend src (s, this);
+  fur_depend src (s, this, &m_cache);
   return f.fold_stmt (r, s, src, name);
 }
 
-- 
2.45.0

Reply via email to