https://gcc.gnu.org/g:6df88a49e162a971f324247b184ddeb76b115ecc

commit r17-1662-g6df88a49e162a971f324247b184ddeb76b115ecc
Author: Andrew MacLeod <[email protected]>
Date:   Wed Jun 17 16:51:15 2026 -0400

    Do not invoke a different range query from within fold_stmt.
    
    fold_using_range works on a specified range_query object.  IF this
    object is not the current_range_query (cfun) object, do not invoke
    the general gimple fold routines as they may call into the current
    query.
    
            PR tree-optimization/125854
            gcc/
            * gimple-range-fold.cc (fold_using_range::fold_stmt): Check if the
            range_query matches the current one before invoking fold.
    
            gcc/testsuite/
            * g++.dg/pr125854.C: New.

Diff:
---
 gcc/gimple-range-fold.cc        |  4 +++-
 gcc/testsuite/g++.dg/pr125854.C | 30 ++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index bae94dfa44ba..50cee517120b 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -757,7 +757,9 @@ fold_using_range::fold_stmt (vrange &r, gimple *s, 
fur_source &src, tree name)
        {
          p.set_pt (rhs, true);
        }
-      else
+      // PR 125854 - Do not attempt to invoke the fold machinery unless this
+      // query is the same as the current query (which fold may invoke).
+      else if (src.query () == get_range_query (cfun))
        {
          // If we couldn't find anything, try fold.
          x_fold_context = { s, src.query () };
diff --git a/gcc/testsuite/g++.dg/pr125854.C b/gcc/testsuite/g++.dg/pr125854.C
new file mode 100644
index 000000000000..d8c38087ac37
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr125854.C
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wno-stringop-overread -std=c++11" } */
+
+int *__distance___last;
+long move___trans_tmp_9;
+void move(int *__first, int *__result) {
+  move___trans_tmp_9 = __distance___last - __first;
+  if (__builtin_expect(move___trans_tmp_9, true))
+    __builtin_memmove(__result, __first, move___trans_tmp_9);
+}
+struct SmallVectorTemplateCommon {
+  void operator[](long);
+};
+struct SmallVectorTemplateBase : SmallVectorTemplateCommon {};
+void erase(int *CI) { move(CI + 1, CI); }
+struct : SmallVectorTemplateBase {
+} FindInOperandList_Ops;
+int Op, ReassociatePassOptimizeAdd___trans_tmp_1;
+unsigned FindInOperandList(unsigned i) {
+  for (unsigned j = i + 1;;)
+    if (FindInOperandList_Ops[j], Op)
+      return j;
+}
+void ReassociatePassOptimizeAdd() {
+  for (unsigned i;; ++i) {
+    FindInOperandList(i);
+    erase(&ReassociatePassOptimizeAdd___trans_tmp_1 + i);
+  }
+}
+

Reply via email to