On 6/5/25 09:28, Richard Biener wrote:
The following uses context sensitive ranger for determining whether
the input to the table based CTZ is ever zero.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
* tree-ssa-forwprop.cc (simplify_count_trailing_zeroes):
Use ranger instead of tree_expr_nonzero_p.
---
gcc/tree-ssa-forwprop.cc | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index 4ef75ba98bd..a60862a4b1a 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -2667,7 +2667,12 @@ simplify_count_trailing_zeroes (gimple_stmt_iterator
*gsi)
int nargs = 2;
/* If the input value can't be zero, don't special case ctz (0). */
- if (tree_expr_nonzero_p (res_ops[0]))
+ range_query *q = get_range_query (cfun);
+ if (q == get_global_range_query ())
+ q = enable_ranger (cfun);
+ int_range_max vr;
+ if (q->range_of_expr (vr, res_ops[0], stmt)
+ && !range_includes_zero_p (vr))
{
zero_ok = true;
zero_val = 0;
You will also need a matching "disable_ranger ()" call if you are
enabling it.
Which brings up a minor flow issue I suppose. You want to use a
context ranger, but you don't know if you have one or not. Right now,
we pair calls to enable_ranger/disable_ranger and leave it up to the
passes turn it on when they want. It also traps to make sure youy dont
make the call when there is already one active. this will cause an issue
in a case like yours because you probably want to keep using it, but the
invoking pass may not have created one.
We could always have the pass manager call disable_ranger() at the end
of a pass, and if there is not an active ranger, have it simply return,
otherwise do the dispose.
Then we adjust enable_ranger to check if there is an active ranger, and
if there is, simply leave it be and return other. Otherwise turn one on
and return it.
This seems like a relatively harmless change since we don't want ranger
active across passes and removes some burden of tracking from the
passes. I had considered making it a pass attribuite, but I think I
like this even better than that... more flexibility.
Then in your case, you would simply call
range_query *q = enable_ranger (cfun);
and you would get either a new one, or the existing one, but are
guaranteed a context ranger.
Does that seem reasonable?
Andrew