On Tue, Jun 23, 2026 at 4:22 AM Kael Andrew Franco
<[email protected]> wrote:
>
> From 56369c999a6fe63a0ba1d1cafa7d555f4f65e7c2 Mon Sep 17 00:00:00 2001
> From: Kael Andrew Alonzo Franco <[email protected]>
> Date: Mon, 22 Jun 2026 22:44:06 -0400
> Subject: [PATCH] match: For C != {-1, 0}, C (==,!=) (C >> a) -> a (==,!=) 0 
> [PR112090]
>
> GCC already covers C (==,!=) (C << a) -> a (==,!=) 0 for C != 0.
>
> Bootstrapped and tested on x86_64-pc-linux-gnu
>
> PR tree-optimization/112090
>
> gcc/ChangeLog:
>
> PR tree-optimization/112090
> * match.pd: For C != {-1, 0}, optimize C (==,!=) (C >> a) to a (==,!=) 0.
>
> gcc/testsuite/ChangeLog:
>
> PR tree-optimization/112090
> * gcc.dg/112090.c: New test.
>
> Signed-off-by: Kael Franco <[email protected]>
> ---
>  gcc/match.pd                    |  8 ++++++++
>  gcc/testsuite/gcc.dg/pr112090.c | 28 ++++++++++++++++++++++++++++
>  2 files changed, 36 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.dg/pr112090.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 8c410c2f3b3..e765cbe3ad7 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -5120,6 +5120,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>   (if (INTEGRAL_TYPE_P (type))
>    (convert (eq:boolean_type_node @2 { build_zero_cst (TREE_TYPE (@2)); }))))
>
> +/* For C != {-1, 0}, C (==,!=) (C >> a) -> a (==,!=) 0  */
> +(for neeq (ne eq)
> + (simplify
> +  (neeq:c @1 (rshift INTEGER_CST@1 @0))
It is better to put the INTEGER_CST on the outermost @1.
Usually the number is in the opposite order too.
So (neeq:c INTEGER_CST@0 (rshift INTEGER_CST@0 @1))

> +   (if (integer_zerop (@1) == 0
> +        && integer_all_onesp (@1) == 0)

(if (!integer_zerop (@1) && !integer_all_onesp (@1))

Though I think both of these will be handled beforehand. So you don't
need the checks here anyways.

> +    (convert (neeq:boolean_type_node @0 { build_zero_cst (TREE_TYPE (@0)); 
> })))))

And then @1 down here.

Otherwise this looks reasonable and correct.

Thanks,
Andrea



> +
>  /* Simplify (CST << x) & 1 to 0 if CST is even or to x == 0 if it is odd.  */
>  (simplify
>   (bit_and (lshift INTEGER_CST@1 @0) integer_onep)
> diff --git a/gcc/testsuite/gcc.dg/pr112090.c b/gcc/testsuite/gcc.dg/pr112090.c
> new file mode 100644
> index 00000000000..3b22f1b5c2b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr112090.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +_Bool
> +pcst_ne_pcst_rshift_a (int a)
> +{
> +  return (11 != (11 >> a)) == (a != 0);
> +}
> +
> +_Bool
> +ncst_ne_ncst_rshift_a (int a)
> +{
> +  return (-11 != (-11 >> a)) == (a != 0);
> +}
> +
> +_Bool
> +pcst_eq_pcst_rshift_a (int a)
> +{
> +  return (11 == (11 >> a)) == (a == 0);
> +}
> +
> +_Bool
> +ncst_eq_ncst_rshift_a (int a)
> +{
> +  return (-11 == (-11 >> a)) == (a == 0);
> +}
> +
> +/* { dg-final { scan-tree-dump-times "return 1;" 4 "optimized" } } */
> --
> 2.54.0
>
>

Reply via email to