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); + } +} +
