[COMMITTED] PR tree-optimization/126814 - fold_using_range should set the current query.

Andrew MacLeod <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
We also ran into this in PR 125854..  so lets fix it permanently.

fold_using_range provides a richer interface where you can choose to 
fold statements using a specified range_query.  If you do not specify 
one, the current_range-query is used.

Ranger's cache counts on being able to call into this interface using 
its own read-only version of the cache, as well as occassional uses 
where the global_range_query is used for safety.    With 
get_range_query(cfun) being used more frequently in simplification, 
folding and other locations, we are starting to trip over it more 
frequently.

In this case, the global_range_query is passed in to be used, but when 
range_of_call is invoked, it checks for gimple_stmt_nonzero_p(), and 
down the call chain eventually tree_expr_nonzero_p() invokes, you 
guessed it, get_range_query ()->range_of_expr.    This escaped the 
read-only range query that was specified, and is causing the 
non-reentrant cache filling to be entered again and trip the assert.

To avoid this i the future, The permanent fix currently  is when 
fold_using_range::fold_stmt is invoked, if the current query doesn't 
match the specified one, replace the current query for the duration of 
the calculations...    then all get_range_query() calls will invoke to 
correct query, and fold_stmt will then replace the current query when 
its done.   All calls from within fold_using_range will then use the 
correct range_query.

This resolves the current PR, and deprecates/replaces the fix for 125854 
as it covers that as well.

Bootstrapped on x86_64-pc-linux-gnu with no regressions.  pushed.

Andrew
0003-fold_using_range-should-set-the-current-query.patch (text/x-patch, 4.7 KB)
From 196f90d7d53cc8e0354f536a85719498f51adc37 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <[email protected]>
Date: Wed, 12 Aug 2026 17:03:21 -0400
Subject: [PATCH 3/4] fold_using_range should set the current query.

	PR tree-optimization/126814
	gcc/
	* gimple-range-fold.cc (fold_using_range::fold_stmt): Temporarily
	replace the current range query with the specified one.

	gcc/testsuite/
	* gcc.dg/pr126814.c: New.
---
 gcc/gimple-range-fold.cc        | 59 +++++++++++++++++++--------------
 gcc/testsuite/gcc.dg/pr126814.c | 17 ++++++++++
 2 files changed, 52 insertions(+), 24 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr126814.c

diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 5a2736c6ebc..a64529603f8 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -690,6 +690,14 @@ fold_using_range::fold_stmt (vrange &r, gimple *s, fur_source &src, tree name)
   if (gimple_code (s) == GIMPLE_ASSIGN && range_from_readonly_var (r, s))
     return true;
 
+  // Save the current range query and restore it before returning.
+  // If the specified query is different, make it the current one.
+  // PR 125854 - The fold machinery may make a query call.
+  // PR 126814 - tree_expr_nonnegative_p may make a call.
+  range_query *save = cfun->x_range_query;
+  if (src.query () != get_range_query (cfun))
+    cfun->x_range_query = src.query ();
+
   gimple_range_op_handler handler (s);
   if (gimple_code (s) == GIMPLE_ASSIGN
       && gimple_assign_rhs_code (s) == ADDR_EXPR)
@@ -722,6 +730,8 @@ fold_using_range::fold_stmt (vrange &r, gimple *s, fur_source &src, tree name)
 
   if (!res)
     {
+      // Restore the original query.
+      cfun->x_range_query = save;
       // If no name specified or range is unsupported, bail.
       if (!name || !gimple_range_ssa_p (name))
 	return false;
@@ -731,7 +741,11 @@ fold_using_range::fold_stmt (vrange &r, gimple *s, fur_source &src, tree name)
     }
 
   if (r.undefined_p ())
-    return true;
+    {
+      // Restore the original query.
+      cfun->x_range_query = save;
+      return true;
+    }
 
   // We sometimes get compatible types copied from operands, make sure
   // the correct type is being returned.
@@ -741,35 +755,32 @@ fold_using_range::fold_stmt (vrange &r, gimple *s, fur_source &src, tree name)
       range_cast (r, TREE_TYPE (name));
     }
 
-  // IF this is not a prange, we are done.
-  if (!is_a <prange> (r))
-    return true;
-
-  prange &p = as_a <prange> (r);
-  // Check to see if points_to should be set.
-  if (p.pt_unknown_p () && name && gimple_code (s) == GIMPLE_ASSIGN)
+  if (is_a <prange> (r))
     {
-      tree rhs = gimple_assign_rhs1 (s);
-      tree_code code = gimple_assign_rhs_code (s);
-      // If code is SSA_NAME, any points to would already be copied.
-      if (code != SSA_NAME && get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS
-	  && TREE_CODE (rhs) == ADDR_EXPR)
+      prange &p = as_a <prange> (r);
+      // Check to see if points_to should be set.
+      if (p.pt_unknown_p () && name && gimple_code (s) == GIMPLE_ASSIGN)
 	{
-	  p.set_pt (rhs, true);
-	}
-      // 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 () };
-	  rhs = gimple_fold_stmt_to_constant_1 (s, pta_valueize, pta_valueize);
-	  if (rhs && TREE_CODE (rhs) == ADDR_EXPR)
+	  tree rhs = gimple_assign_rhs1 (s);
+	  tree_code code = gimple_assign_rhs_code (s);
+	  // If code is SSA_NAME, any points to would already be copied.
+	  if (code != SSA_NAME
+	      && get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS
+	      && TREE_CODE (rhs) == ADDR_EXPR)
+	    p.set_pt (rhs, true);
+	  else
 	    {
-	      p.set_pt (rhs, true);
+	      // If we couldn't find anything, try fold.
+	      x_fold_context = { s, src.query () };
+	      rhs = gimple_fold_stmt_to_constant_1 (s, pta_valueize,
+						    pta_valueize);
+	      if (rhs && TREE_CODE (rhs) == ADDR_EXPR)
+		p.set_pt (rhs, true);
 	    }
 	}
     }
+  // Restore the original query.
+  cfun->x_range_query = save;
   return true;
 }
 
diff --git a/gcc/testsuite/gcc.dg/pr126814.c b/gcc/testsuite/gcc.dg/pr126814.c
new file mode 100644
index 00000000000..b7a937d9c98
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr126814.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -funsafe-math-optimizations" } */
+
+float r;
+void use (int);
+
+void
+check (int n)
+{
+  for (int j = 0; j < n; j++)
+    {
+      int y = (int) __builtin_ceilf (j * r);
+      if (y >= n)
+        y = -n;
+      use (y * 4);
+    }
+}
-- 
2.45.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.