On Tue, Aug 11, 2026 at 8:50 PM <[email protected]> wrote:
>
> From: Reshma Roy <[email protected]>
>
> gcc/ChangeLog:
>
> PR tree-optimization/126646
> * match.pd: Fold umin(a, 1) | umin(b, 1) into umin(a | b, 1).
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/tree-ssa/pr126646-1.c: New test.
> ---
>
> Hi,
> This patch fixes the missed optimization opportunity reported in
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126646.
> For the following snippet of code, gcc generates 2 MIN_EXPR.
> unsigned f(unsigned a, unsigned b)
> {
> unsigned t = 1;
> a = a < t ? a : t;
> b = b < t ? b : t;
> return a | b;
> }
> But this can be optimized with just one MIN_EXPR since
> umin(a,1) | umin(b,1) can be simplified to umin(a|b, 1).
>
> Bootstrapped and tested on x86_64-linux.
>
> Thanks,
> Reshma
>
> gcc/match.pd | 5 +++++
> gcc/testsuite/gcc.dg/tree-ssa/pr126646-1.c | 15 +++++++++++++++
> 2 files changed, 20 insertions(+)
> create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr126646-1.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 50e73177022..7347b83ec4f 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -4860,6 +4860,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> (bit_not (minmax:cs (bit_not @0) @1))
> (maxmin @0 (bit_not @1))))
>
> +/* umin (a, 1) | umin (b, 1) -> umin (a | b, 1). */
> + (simplify
> + (bit_ior (min @0 integer_onep@2) (min @1 @2))
> + (if (TYPE_UNSIGNED (type))
Instead of TYPE_UNSIGNED here; I think it might be a good idea to use
tree_expr_nonnegative_p on both @0 and @1..
tree_expr_nonnegative_p does return true for TYPE_UNSIGNED already but
it also returns true when the argument is known to be zero or
positive.
This allows for say:
```
int f(int a, int b)
{
int c = 0;
if (a >= 0 && b >= 0)
c = (a > 1 ? 1 : a) | (b > 1 ? 1 : b);
return c;
}
```
Which then should optimize to just:
_10 = a_6(D) | b_7(D);
c_8 = MIN_EXPR <_10, 1>;
_11 = MAX_EXPR <c_8, 0>;
Thanks,
Andrea
> + (min (bit_ior @0 @1) @2)))
> /* MIN (X, Y) == X -> X <= Y */
> /* MIN (X, Y) < X -> X > Y */
> /* MIN (X, Y) >= X -> X <= Y */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr126646-1.c
> b/gcc/testsuite/gcc.dg/tree-ssa/pr126646-1.c
> new file mode 100644
> index 00000000000..447a1739b5f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr126646-1.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +/* The test case should produce only one min expr. */
> +/* umin(a,1) | umin(b,1) -> umin(a|b, 1). */
> +
> +unsigned min_or (unsigned a, unsigned b)
> +{
> + unsigned t = 1;
> + a = a < t ? a : t;
> + b = b < t ? b : t;
> + return a | b;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "optimized" } } */
> --
> 2.34.1
>