https://gcc.gnu.org/g:ce4b6019b8758b04a8733bc672adbbaa384c752a

commit r17-4907-gce4b6019b8758b04a8733bc672adbbaa384c752a
Author: Andrew MacLeod <[email protected]>
Date:   Mon Oct 5 09:46:48 2026 -0400

    Clear range info when freeing an ssa name.
    
    When an ssa name is being released, clear any current range 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!  It also wasn't clearing the import field.
    
            PR tree-optimization/127719
            gcc
            * gimple-range-gori.cc (range_def_chain::clear): Do not
            recalculate a def chain when it has just been cleared.
            * tree-ssanames.cc (release_ssa_name_fn): Clear range info.
    
            gcc/testsuite/
            * gcc.dg/pr127719.c: New.
            * g++.dg/pr127729.C: New.

Diff:
---
 gcc/gimple-range-gori.cc        |  2 +-
 gcc/testsuite/g++.dg/pr127729.C | 56 +++++++++++++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/pr127719.c | 18 +++++++++++++
 gcc/tree-ssanames.cc            |  5 ++++
 4 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index d34c2b79a7c8..7d62cb184988 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -307,7 +307,7 @@ range_def_chain::clear (tree name)
   m_def_chain[v].ssa1 = 0;
   m_def_chain[v].ssa2 = 0;
   m_def_chain[v].bm = NULL;
-  get_def_chain (name);
+  m_def_chain[v].m_import = NULL;
 }
 
 // Dump what we know for basic block BB to file F.
diff --git a/gcc/testsuite/g++.dg/pr127729.C b/gcc/testsuite/g++.dg/pr127729.C
new file mode 100644
index 000000000000..c28de0f255ab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr127729.C
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+enum E {};
+bool getKnownMinValue();
+struct TypeSize {
+  bool Scalable;
+} getSizeInBits_SizeTable;
+extern TypeSize SizeTable[];
+void isKnownGT(TypeSize);
+struct MVT {
+  E SimpleTy;
+} V, LowerFCOPYSIGN___trans_tmp_10;
+E getSizeInBits_e_0;
+static void knownBitsGT(MVT e, MVT VT) {
+  TypeSize __trans_tmp_4, __trans_tmp_1;
+  switch (VT.SimpleTy)
+  case 0:
+  case 2:
+    __trans_tmp_1 = getSizeInBits_SizeTable;
+  switch (e.SimpleTy) {
+  case 0:
+  case 2:
+  case 3:
+    __builtin_unreachable();
+  default:
+    __trans_tmp_4 = SizeTable[e.SimpleTy];
+  }
+  isKnownGT(__trans_tmp_4);
+  isKnownGT(__trans_tmp_1);
+}
+static bool knownBitsLT(MVT e) {
+  switch (getSizeInBits_e_0)
+  case 2:
+    __builtin_unreachable();
+  switch (e.SimpleTy)
+  case 0:
+  case 2:
+  case 3:
+    __builtin_unreachable();
+  TypeSize LHS;
+  if (LHS.Scalable)
+    return getKnownMinValue();
+  return false;
+}
+bool LowerFCOPYSIGN_bl;
+void LowerFCOPYSIGN() {
+  MVT __trans_tmp_12, __trans_tmp_11 = LowerFCOPYSIGN___trans_tmp_10,
+                      __trans_tmp_7 = __trans_tmp_11, VT;
+  LowerFCOPYSIGN_bl = knownBitsLT(__trans_tmp_7);
+  if (LowerFCOPYSIGN_bl)
+    LowerFCOPYSIGN___trans_tmp_10 = V;
+  __trans_tmp_12 = LowerFCOPYSIGN___trans_tmp_10;
+  MVT __trans_tmp_8 = __trans_tmp_12;
+  knownBitsGT(__trans_tmp_8, VT);
+}
diff --git a/gcc/testsuite/gcc.dg/pr127719.c b/gcc/testsuite/gcc.dg/pr127719.c
new file mode 100644
index 000000000000..c1a208f033b3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr127719.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned short a;
+unsigned b;
+void c() {
+  char d = b;
+  long e = b + (a & 5ull) & 1;
+  if ((unsigned long)b - 2 + e)
+    if (e)
+      __builtin_unreachable();
+  do {
+    d >>= e;
+    if (d)
+      break;
+  } while (1);
+}
+int main() {}
diff --git a/gcc/tree-ssanames.cc b/gcc/tree-ssanames.cc
index 8eac57f42cba..603bdc430980 100644
--- a/gcc/tree-ssanames.cc
+++ b/gcc/tree-ssanames.cc
@@ -692,6 +692,11 @@ 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);

Reply via email to