>
> On 10/27/25 10:25, Robin Dapp wrote:
>>> Hmm, code does not match comment?  I think you want r.nonzero_p ().
>>> But that also means that at (*) we cannot simply leave 'r' to be the
>>> range of the unshifted src.
>>>
>>>> +       assumptions = boolean_true_node;
>>>> +    }
>>>> +
>>>> +  /* If that didn't work use simplify_using_initial_conditions.  */
>>>> +  if (assumptions == boolean_false_node)
>> Yeah, I originally used the path-based ranger and had an inverse condition.
>> Then I removed it and swapped the condition, realizing that things still 
>> work.
>> But they don't actually... as only a path-based approach has enough 
>> information
>> but the boundary conditions here are constricted enough that my test case 
>> still
>> passes (similar to v1) because nonzero_p is also the wrong check...
>>
>> I re-introduced the path-based approach now, using a helper function, and
>> re-tested everything on x86, rv64gcv_zvl512b, and power10 in the attached v3.
>>
>> Regards
>
>
> You should not need  path ranger to do this, a normal ranger should be 
> enough.
>
>>   
>> +/* Helper for number_of_iterations_cltz that uses path-based ranger to
>> +   determine if SRC, shifted left (when LEFT_SHIFT is true) or right
>> +   by NUM_IGNORED_BITS, is guaranteed to be != 0 inside LOOP.
>> +   Return true if so or false otherwise.  */
>> +
>> +static bool
>> +shifted_range_nonzero_p (loop_p loop, tree src,
>> +                     bool left_shift, int num_ignored_bits)
>> +{
>> +  int_range_max r (TREE_TYPE (src));
>> +  gcc_assert (num_ignored_bits >= 0);
>> +
>> +  auto_vec<basic_block, 2> path;
>> +  path.safe_push (loop->header);
>> +  path.safe_push (loop_preheader_edge (loop)->src);
>> +
>> +  bool range_nonzero = false;
>> +  gimple_ranger ranger;
>> +  path_range_query query (ranger, path);
>> +
>> +  if (query.range_of_expr (r, src)
> THis will only pick up a global  value for src.  If I look at where ou 
> are calling from,
>
>     tree src = gimple_phi_arg_def (phi, loop_preheader_edge (loop)->dest_idx);
>
> I presume what you are looking for is the value of src coming in on that 
> edge?
>
> in which case you should only have to do
>
> if (get_range_query (cfun)->range_on_edge (r, loop_preheader_edge 
> (loop), src))
>
> to get the range.. which  is what you were doing in the original patch.
>
> In the latest version of the patch that doesn't use the path ranger,  is 
> there an active ranger?  (ie, the enable_ranger () call) .  If not, all 
> you will get is global values again.
>
> Whats the current version of the patch, using the get_range_query()-> 
> range_on_edge ()      ?

The loop is roughly:

  if (bits)
   {
    if (!(bits & 1)
    {
      do
        {
          bits >>= 1;
          cnt += 1;
        } while (!(bits & 1));

and we need to prove that bits >> 1 != 0 in order to know the loop terminates.

  get_range_query (cfun)->range_on_edge (r, loop_preheader_edge (loop), src)

returned a varying range but the "path-based" approach seemed to work.
I was hoping that a path-based approach would combine the conditions
bits != 0 && (bits & 1) == 0, and that was what I appeared to be getting.

You're saying that the way I used it is not path-based?  I didn't explicitly 
call enable_ranger () but adding the preheader and loop header path as in v3 
still got me different results than just the range-on-edge query.

-- 
Regards
 Robin

Reply via email to