On Tue, Jun 16, 2026 at 10:44 PM Naveen
<[email protected]> wrote:
>
> The patch adds simplifications for the pattern where a sign-bit check and a
> lower-bits check are combined with a bitwise or logical AND/OR:
>
>   (1) ((signed)A >= 0) &/&& ((A & INT_MAX) != 0)  -->  (signed)A > 0
>   (2) ((signed)A <  0) |/|| ((A & INT_MAX) == 0)  -->  (signed)A <= 0
>
> Both patterns arise naturally from code that separately tests the sign
> bit and the magnitude of an unsigned integer.  The combined expression
> is equivalent to a single signed comparison, and the simplification
> eliminates the intermediate BIT_AND_EXPR mask as well as the weaker
> comparison operator.
>
> Bootstrapped and tested on aarch64-linux-gnu.

Ok.

>
> gcc/ChangeLog:
>         PR tree-optimization/112390
>         * match.pd: Add simplifications for combined sign-bit and
>         magnitude checks:
>         ((signed)A >= 0) &/&& ((A & INT_MAX) != 0) -> (signed)A > 0
>         ((signed)A <  0) |/|| ((A & INT_MAX) == 0) -> (signed)A <= 0
>
> gcc/testsuite/ChangeLog:
>         PR tree-optimization/112390
>         * gcc.dg/pr112390.c: New test.
>         * gcc.dg/pr112390_bitint.c: New test.
>
> Signed-off-by: Naveen <[email protected]>
> ---
>  gcc/match.pd                           | 16 +++++
>  gcc/testsuite/gcc.dg/pr112390.c        | 93 ++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/pr112390_bitint.c | 20 ++++++
>  3 files changed, 129 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.dg/pr112390.c
>  create mode 100644 gcc/testsuite/gcc.dg/pr112390_bitint.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 475939a0b63..ea3b270b3ff 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -1730,6 +1730,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>       (convert (bit_and (negate (convert:utype { pmop[0]; }))
>                        (convert:utype @1)))))))
>
> +/* (signed)A >= 0 && (A & INT_MAX) != 0  -->  (signed)A > 0
> +   (signed)A <  0 || (A & INT_MAX) == 0  -->  (signed)A <= 0  */
> +(for op      (bit_and  truth_and  bit_ior  truth_or)
> +     signop  (ge       ge         lt       lt)
> +     maskop  (ne       ne         eq       eq)
> +     resop   (gt       gt         le       le)
> + (simplify
> +  (op:c
> +   (signop (nop_convert?@2 @0) integer_zerop)
> +   (maskop (bit_and @0 INTEGER_CST@3) integer_zerop))
> +  (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
> +       && !TYPE_UNSIGNED (TREE_TYPE (@2))
> +       && wi::eq_p (wi::to_wide (@3),
> +                   wi::max_value (TYPE_PRECISION (TREE_TYPE (@0)), SIGNED)))
> +   (resop @2 { build_zero_cst (TREE_TYPE (@2)); }))))
> +
>  /* X % Y is smaller than Y.  */
>  (for cmp (lt ge)
>   (simplify
> diff --git a/gcc/testsuite/gcc.dg/pr112390.c b/gcc/testsuite/gcc.dg/pr112390.c
> new file mode 100644
> index 00000000000..e28bfca4639
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr112390.c
> @@ -0,0 +1,93 @@
> +/* PR tree-optimization/112390 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +#include <limits.h>
> +
> +int f32_bitand(unsigned int a)
> +{
> +  return ((int)a >= 0) & ((a & (unsigned)INT_MAX) != 0);
> +}
> +
> +int f32_truthand(unsigned int a)
> +{
> +  return ((int)a >= 0) && ((a & (unsigned)INT_MAX) != 0);
> +}
> +
> +int f32_bitior(unsigned int a)
> +{
> +  return ((int)a < 0) | ((a & (unsigned)INT_MAX) == 0);
> +}
> +
> +int f32_truthor(unsigned int a)
> +{
> +  return ((int)a < 0) || ((a & (unsigned)INT_MAX) == 0);
> +}
> +
> +int f32s_bitand(int a)
> +{
> +  return (a >= 0) & ((a & INT_MAX) != 0);
> +}
> +
> +int f32s_truthand(int a)
> +{
> +  return (a >= 0) && ((a & INT_MAX) != 0);
> +}
> +
> +int f32s_bitior(int a)
> +{
> +  return (a < 0) | ((a & INT_MAX) == 0);
> +}
> +
> +int f32s_truthor(int a)
> +{
> +  return (a < 0) || ((a & INT_MAX) == 0);
> +}
> +
> +int f64_bitand(unsigned long long a)
> +{
> +  return ((long long)a >= 0) & ((a & (unsigned long long)LLONG_MAX) != 0);
> +}
> +
> +int f64_truthand(unsigned long long a)
> +{
> +  return ((long long)a >= 0) && ((a & (unsigned long long)LLONG_MAX) != 0);
> +}
> +
> +int f64_bitior(unsigned long long a)
> +{
> +  return ((long long)a < 0) | ((a & (unsigned long long)LLONG_MAX) == 0);
> +}
> +
> +int f64_truthor(unsigned long long a)
> +{
> +  return ((long long)a < 0) || ((a & (unsigned long long)LLONG_MAX) == 0);
> +}
> +
> +int f64s_bitand(long long a)
> +{
> +  return (a >= 0) & ((a & LLONG_MAX) != 0);
> +}
> +
> +int f64s_truthand(long long a)
> +{
> +  return (a >= 0) && ((a & LLONG_MAX) != 0);
> +}
> +
> +int f64s_bitior(long long a)
> +{
> +  return (a < 0) | ((a & LLONG_MAX) == 0);
> +}
> +
> +int f64s_truthor(long long a)
> +{
> +  return (a < 0) || ((a & LLONG_MAX) == 0);
> +}
> +
> +/* { dg-final { scan-tree-dump-times ">= 0" 0 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "< 0" 0 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "BIT_AND_EXPR" 0 "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "bit_and" "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "bit_ior" "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "> 0" 8 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "<= 0" 8 "optimized" } } */
> diff --git a/gcc/testsuite/gcc.dg/pr112390_bitint.c 
> b/gcc/testsuite/gcc.dg/pr112390_bitint.c
> new file mode 100644
> index 00000000000..764be94b72b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr112390_bitint.c
> @@ -0,0 +1,20 @@
> +/* PR tree-optimization/112390 - _BitInt variants */
> +/* { dg-do compile { target bitint } } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +int fbit11_ior(unsigned _BitInt(11) a)
> +{
> +  signed _BitInt(11) sa = (signed _BitInt(11))a;
> +  return (sa < 0) | ((a & 1023wb) == 0);
> +}
> +
> +int fbit11_and(unsigned _BitInt(11) a)
> +{
> +  signed _BitInt(11) sa = (signed _BitInt(11))a;
> +  return (sa >= 0) & ((a & 1023wb) != 0);
> +}
> +
> +/* { dg-final { scan-tree-dump-not "bit_and" "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "bit_ior" "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "> 0" 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "<= 0" 1 "optimized" } } */
> --
> 2.34.1
>

Reply via email to