On 10/6/26 3:31 AM, Richard Biener wrote:
On Mon, Oct 5, 2026 at 9:11 PM Andrew MacLeod <[email protected]> wrote:
The testcase triggers a problem that when an ssa_name was released by
simple_dce_from_worklist.  The same name was then used from a cached
value i the relation oracle.  This patch modifies release_ssa_name_fn
such that when an ssa name is being released, it also clear any current
range info.   THis is similar to what is done during
reset_flow_sensitive_info ().

This also uncovered a bug in the def chains where clearing the def chain
immediately rebuilds it.  This is inadvisable when the name is being
released!

Bootstrapped on x86_64-pc-linux-gnu with no new regressions. Pushed.
Hmm.  A ranger instance does not have to be in fn->x_range_query
(only with enable/disable_ranger ())?  Also this feels a bit expensive - we
have arranged for released SSA names to be not re-usable immediately
by the current pass via dual free-lists, so a lazy approach should work
and queries to released SSA names can instead be catched in the
range oracle itself (for example by checking SSA_NAME_ON_FREELIST)


Hmm. In theory every single request would have to do the check if the name is in the free list..  but in practice, I don't think that is necessary.

I was also debating a follow up to change the 2 locations which fire up their own ranger (ch and threadbackward) to call enable _ranger... but I don't think that is needed either.

However, we can also argue that this hasn't been an issue for any of the other cached values, it is just the new frontier expansion which is triggering the problem, so I can revert the change to release_ssa_name_fn and instead check the free list while doing the frontier expansion.    That will cover the new code, and leave everything else as they are.

valid_equivs in the oracle also uses this idiom already, so I think that should be good enough.  I added this patch as a follow up which reverts the change to release_ssa_name..   So if there ever is a future problem related other cached values, this commit will show up as the the cause and maybe help us figure it out quicker.

Patch attached.  Bootstrapped on x86_64-pc-linux-gnu with no new regressions. Pushed.

Andrew


From a093d2b35b7becc22d257118b9d787bb1d79de61 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <[email protected]>
Date: Tue, 6 Oct 2026 10:05:59 -0400
Subject: [PATCH] Check free list before using a relation.

Rather than calling reset_range_Info in release_ssa_name_fn, lazily
check the free list when registering nearest relations to avoid returning
a relation with a released ssa-name.

	PR tree-optimization/127719
	gcc/
	* tree-ssanames.cc (release_ssa_name_fn): Do not call
	reset_range_info.
	* value-relation.cc (dom_oracle::nearest_relations): Check the
	free list before adding a name to the relation list.
---
 gcc/tree-ssanames.cc  | 5 -----
 gcc/value-relation.cc | 6 ++++--
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/gcc/tree-ssanames.cc b/gcc/tree-ssanames.cc
index 603bdc43098..8eac57f42cb 100644
--- a/gcc/tree-ssanames.cc
+++ b/gcc/tree-ssanames.cc
@@ -692,11 +692,6 @@ release_ssa_name_fn (struct function *fn, tree var)
       int saved_ssa_name_version = SSA_NAME_VERSION (var);
       use_operand_p imm = &(SSA_NAME_IMM_USE_NODE (var));
 
-      /* An active range query caches information keyed off both VAR and its
-	 version, communicate that this node is about to be cleared.  */
-      if (fn->x_range_query)
-	fn->x_range_query->reset_range_info (var);
-
       if (MAY_HAVE_DEBUG_BIND_STMTS)
 	insert_debug_temp_for_var_def (NULL, var);
 
diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc
index cfef9fcd68d..be4f1aaf784 100644
--- a/gcc/value-relation.cc
+++ b/gcc/value-relation.cc
@@ -1857,9 +1857,11 @@ dom_oracle::nearest_relations (tree name, basic_block bb)
       for (relation_chain *ptr = m_relations[bb->index].m_head;
 	   ptr; ptr = ptr->m_next)
 	{
-	  if (v == SSA_NAME_VERSION (ptr->op1 ()))
+	  if (v == SSA_NAME_VERSION (ptr->op1 ())
+	      && !SSA_NAME_IN_FREE_LIST (ptr->op2 ()))
 	    m_near.safe_push ({ ptr->kind (), ptr->op2 (), bb });
-	  else if (v == SSA_NAME_VERSION (ptr->op2 ()))
+	  else if (v == SSA_NAME_VERSION (ptr->op2 ())
+		   && !SSA_NAME_IN_FREE_LIST (ptr->op1 ()))
 	    m_near.safe_push ({ relation_swap (ptr->kind ()),
 				ptr->op1 (), bb });
 	}
-- 
2.55.0

Reply via email to