The original patch causing the PR made ranger's cache re-entrant to
enable SCEV to use the current range_query when called from within ranger..
SCEV uses the currently active range query (via get_range_query()) for
picking up values. fold_using_range is the general purpose stmt folder
many components use, and it takes a range_query to use for folding.
When propagating values in the cache, we need to ensure no new queries
are invoked, and when the cache is propagating and calculating outgoing
edges, it switches to a read only range_query which uses what it knows
about global values to come up with best result using current state.
SCEV is unaware of what the caller is using for a range_query, so when
attempting to fold a PHI node, it is re-invoking the current query
during propagation which is undesired behavior. This patch tells
fold_using_range to not use SCEV if the range_query being used is not
the same as the one SCEV is going to use.
Bootstrapped on x86_64-pc-linux-gnu with no regressions. Pushed.
Andrew
From b814e390e7c87c14ce8d9cdea6c6cd127a4e6261 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacl...@redhat.com>
Date: Mon, 27 May 2024 11:00:57 -0400
Subject: [PATCH] Do not invoke SCEV if it will use a different range query.
SCEV always uses the current range_query object.
Ranger's cache uses a global value_query when propagating cache values to
avoid re-invoking ranger during simple vavhe propagations.
when folding a PHI value, SCEV can be invoked, and since it alwys uses
the current range_query object, when ranger is active this causes the
undesired re-invoking of ranger during cache propagation.
This patch checks to see if the fold_using_range specified range_query
object is the same as the one SCEV uses, and does not invoke SCEV if
they do not match.
PR tree-optimization/115221
gcc/
* gimple-range-fold.cc (range_of_ssa_name_with_loop_info): Do
not invoke SCEV is range_query's do not match.
gcc/testsuite/
* gcc.dg/pr115221.c: New.
---
gcc/gimple-range-fold.cc | 6 +++++-
gcc/testsuite/gcc.dg/pr115221.c | 29 +++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.dg/pr115221.c
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index b3965b5ee50..98a4877ba18 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -1264,7 +1264,11 @@ fold_using_range::range_of_ssa_name_with_loop_info (vrange &r, tree name,
fur_source &src)
{
gcc_checking_assert (TREE_CODE (name) == SSA_NAME);
- if (!range_of_var_in_loop (r, name, l, phi, src.query ()))
+ // SCEV currently invokes get_range_query () for values. If the query
+ // being passed in is not the same SCEV will use, do not invoke SCEV.
+ // This can be remove if/when SCEV uses a passed in range-query.
+ if (src.query () != get_range_query (cfun)
+ || !range_of_var_in_loop (r, name, l, phi, src.query ()))
r.set_varying (TREE_TYPE (name));
}
diff --git a/gcc/testsuite/gcc.dg/pr115221.c b/gcc/testsuite/gcc.dg/pr115221.c
new file mode 100644
index 00000000000..f139394e5c0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr115221.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef unsigned uint32_t;
+int cde40_t;
+int offset;
+void aal_test_bit();
+uint32_t cde40_key_pol();
+long cde40_offset_check(uint32_t pos) {
+ cde40_key_pol();
+ if (cde40_t)
+ return (offset - 2) % (((pos == 3) ? 18 : 26)) != 0;
+ return 0;
+}
+void cde40_check_struct() {
+ uint32_t i, j, to_compare;
+ for (;; i++) {
+ cde40_offset_check(i);
+ if (to_compare == 0) {
+ if (i && cde40_key_pol())
+ ;
+ to_compare = i;
+ continue;
+ }
+ j = to_compare;
+ for (; j < i; j++)
+ aal_test_bit();
+ }
+}
--
2.41.0