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?