This is a summary of discussions relative to the merge request created by 
Samarth Tandale (sam-100) <[email protected]> titled
match: Simplify value-range guarded min/max expressions [PR125700]
since its creation.

Description: The pattern:

        x == C ? y : min (x, y)

can be simplified to min (x, y) whenever C >= upper_bound (y),
because min (C, y) == y for all values y can take.  Similarly:

        x == C ? y : max (x, y)

can be simplified to max (x, y) whenever C <= lower_bound (y).

Use ranger to query the value range of y and check the bound condition.

        PR tree-optimization/125700

gcc/ChangeLog:
        PR tree-optimization/125700
        * match.pd ((x == C) ? y : MIN/MAX (x, y)): New simplification.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/pr125700.c: New test.
        * gcc.dg/tree-ssa/pr125700-int-width.c: New test.
        * gcc.dg/tree-ssa/pr125700-negative.c: New test.
        * gcc.dg/tree-ssa/pr125700-range.c: New test.

Signed-off-by: Samarth Tandale <[email protected]>

Testing:
Regression tested a cross compiler targeting AArch64 GNU/Linux on an
x86_64 GNU/Linux host, with execution tests run under QEMU; no
regressions found.

Changes since v1:
- Extended the optimization beyond fixed type limits. It now handles constants
  when Ranger proves their relationship with y's value range and conservatively
  falls back when no useful range is available.
- Added positive and negative test cases for Ranger-derived ranges.

CC: [email protected]

The full and up to date discussion can be found at 
https://forge.sourceware.org/gcc/gcc/pulls/214

The merge request has been closed without being merged directly on the forge 
repository.

On 2026-08-10 06:35:20+00:00, Drea Pinski (pinskia) <[email protected]> 
requested changes to the code:


> +++ gcc/match.pd
> @@ -12710,0 +12719,4 @@
> +   (with {
> +     tree bound = (minmax == MIN_EXPR)
> +               ? TYPE_MAX_VALUE (type)
> +               : TYPE_MIN_VALUE (type);
I think we should use the ranger here.
Similar to minmax_from_comparison.
It should be something like
```
          int_range_max r;
          get_range_query (cfun)->range_of_expr (r, @0);
          if (r.undefined_p ())
            r.set_varying (TREE_TYPE (@0));
          widest_int value;
          if (minmax == MIN_EXPR)
            value = widest_int::from (r.upper_bound (),
                                                     TYPE_SIGN (TREE_TYPE 
(@0)));
          else
            value = widest_int::from (r.lower_bound (),
                                                     TYPE_SIGN (TREE_TYPE 
(@0)));
```
Then the if would be:
          if (max == wi::to_widdest (@0))
> +++ gcc/match.pd
> @@ -12710,0 +12719,4 @@
> +   (with {
> +     tree bound = (minmax == MIN_EXPR)
> +               ? TYPE_MAX_VALUE (type)
> +               : TYPE_MIN_VALUE (type);
I tried using the ranger as suggested. However, get_range_query 
(cfun)->range_of_expr (r, @0) does not to consider the conditional context in 
which @0 is being queried, so it does not provide the path-specific range 
established by the surrounding condition.

I also tried gimple_match_range_of_expr (r, @0, @0). However, the helper uses 
gimple_match_ctx (@0), which provides the definition statement of @0 as the 
context. In this case, that statement is outside the if (x <= 100) block, so 
the conditional range is still not considered.

Could you please verify whether this is the intended use of the ranger, or 
advise how to query the range of @0 using the current conditional context?

Reply via email to