[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