Inferred range elements are stored in a list per basic block. The elements have a pointer to the statement which caused the inferred range, but its only use is to indicate the block that it is in which is now used by clear ().

Elements should refer to the block index directly, thus avoiding any issues with statements being removed, etc.

bootstrapped on x86_64-pc-linux-gnu with no regressions.

Andrew




From 3960440176ad176d98a36b6f5554b340460ff381 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <[email protected]>
Date: Mon, 24 Aug 2026 13:50:04 -0400
Subject: [PATCH 1/2] Infer element should have basic block, not statement.

Inferred range elements are stored in a list per basic block, the
elements should refer back to that block rather than the originating
statement.  Their only use is to indicate which block list they may need
to be removed from.

	PR tree-optimization/127027
	gcc/
	* gimple-range-infer.cc (exit_range::bbi): Change from stmt.
	(infer_range_manager::add_range): Update block index not stmt.
	(infer_range_manager::clear): Remove from specified block list.

	gcc/testsuite/
	* gcc.dg/pr127027.c: New.
---
 gcc/gimple-range-infer.cc       |  9 +++------
 gcc/testsuite/gcc.dg/pr127027.c | 22 ++++++++++++++++++++++
 2 files changed, 25 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr127027.c

diff --git a/gcc/gimple-range-infer.cc b/gcc/gimple-range-infer.cc
index 7dea875cb86..b2f39b37dd4 100644
--- a/gcc/gimple-range-infer.cc
+++ b/gcc/gimple-range-infer.cc
@@ -308,7 +308,7 @@ class exit_range
 {
 public:
   tree name;
-  gimple *stmt;
+  unsigned bbi;
   vrange_storage *range;
   exit_range *next;
   exit_range *name_link;
@@ -486,7 +486,6 @@ infer_range_manager::add_range (tree name, gimple *s, const vrange &r)
 	ptr->range->set_vrange (cur);
       else
 	ptr->range = m_range_allocator->clone (cur);
-      ptr->stmt = s;
       return;
     }
 
@@ -495,7 +494,7 @@ infer_range_manager::add_range (tree name, gimple *s, const vrange &r)
   ptr = (exit_range *)obstack_alloc (&m_list_obstack, sizeof (exit_range));
   ptr->range = m_range_allocator->clone (r);
   ptr->name = name;
-  ptr->stmt = s;
+  ptr->bbi =  bb->index;
   ptr->next = m_on_exit[bb->index].head;
   ptr->name_link = m_name_info[SSA_NAME_VERSION (name)].name_link;
   m_name_info[SSA_NAME_VERSION (name)].name_link = ptr;
@@ -552,9 +551,7 @@ infer_range_manager::clear(tree name)
   exit_range *ptr = m_name_info[v].name_link;
   for ( ; ptr ; ptr = ptr->name_link)
     {
-      basic_block bb = gimple_bb (ptr->stmt);
-      unsigned bbi = bb->index;
-      bitmap_clear_bit (m_on_exit[bbi].m_names, v);
+      bitmap_clear_bit (m_on_exit[ptr->bbi].m_names, v);
       ptr->name = NULL;
     }
 
diff --git a/gcc/testsuite/gcc.dg/pr127027.c b/gcc/testsuite/gcc.dg/pr127027.c
new file mode 100644
index 00000000000..adc4be91d38
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr127027.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct extent_hooks_s {
+  _Bool dalloc;
+};
+typedef struct {
+  void *repr;
+} atomic_p_t;
+atomic_p_t atomic_load_p_a;
+enum { extent_state_muzzy } ehooks_are_default() {
+  _Bool __trans_tmp_3;
+  struct extent_hooks_s *__trans_tmp_2;
+  if (ehooks_are_default()) {
+    void *result;
+    __atomic_load(&atomic_load_p_a, &result, 0);
+    __trans_tmp_2 = result;
+    __trans_tmp_3 = __trans_tmp_2->dalloc;
+  }
+  if (__trans_tmp_3)
+    __builtin_unreachable();
+}
-- 
2.55.0

Reply via email to