From 5193b9d250a8ecec669a87708a1a98abae94130f Mon Sep 17 00:00:00 2001 From: Matteo Nicoli Date: Sat, 4 Oct 2025 09:22:54 -0600 Subject: [PATCH] [PATCH][PR tree-optimization/117760] `a != b` implies that a or b is also non-zero Implements a match.pd pattern to optimize the cases found in PR 117760. PR tree-optimization/117760 gcc/ * match.pd: Add simplifications that exploit implied values after logical tests. gcc/testsuite * gcc.dg/int-bwise-opt-1.c: New test. * gcc.dg/int-bwise-opt-2.c: New test. --- gcc/match.pd | 28 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/int-bwise-opt-1.c | 31 ++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/int-bwise-opt-2.c | 15 +++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/int-bwise-opt-1.c create mode 100644 gcc/testsuite/gcc.dg/int-bwise-opt-2.c diff --git a/gcc/match.pd b/gcc/match.pd index b3fd26e18dd..6f896aa7961 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -6808,6 +6808,34 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) @2)) ) +#if GIMPLE +/* Given two integers a and b: + (a != b) & ((a|b) != 0) -> (a != b) + (a != b) | ((a|b) != 0) -> ((a|b) != 0) + (a == b) & ((a|b) == 0) -> ((a|b) == 0) + (a == b) | ((a|b) == 0) -> (a == b) + (a != b) & ((a|b) == 0) -> false + (a == b) | ((a|b) != 0) -> true */ +(simplify + (bit_and:c (ne:c @0 @1) (ne (bit_ior @0 @1) integer_zerop)) + (ne @0 @1)) +(simplify + (bit_ior:c (ne:c @0 @1) (ne (bit_ior @0 @1) integer_zerop)) + (ne (bit_ior @0 @1) { integer_zero_node; })) +(simplify + (bit_and:c (eq:c @0 @1) (eq (bit_ior @0 @1) integer_zerop)) + (eq (bit_ior @0 @1) { integer_zero_node; })) +(simplify + (bit_ior:c (eq:c @0 @1) (eq (bit_ior @0 @1) integer_zerop)) + (eq @0 @1)) +(simplify + (bit_and:c (ne:c @0 @1) (eq (bit_ior @0 @1) integer_zerop)) + { build_zero_cst (type); }) +(simplify + (bit_ior:c (eq:c @0 @1) (ne (bit_ior @0 @1) integer_zerop)) + { build_one_cst (type); }) +#endif + /* These was part of minmax phiopt. */ /* Optimize (a CMP b) ? minmax : minmax to minmax, c> */ diff --git a/gcc/testsuite/gcc.dg/int-bwise-opt-1.c b/gcc/testsuite/gcc.dg/int-bwise-opt-1.c new file mode 100644 index 00000000000..11ea9acb3fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/int-bwise-opt-1.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int f1(int a, int b) +{ + return (a != b) & ((a | b) != 0); +} + +int f2(int a, int b) +{ + return (a == b) | ((a | b) == 0); +} + +int f3(int a, int b) +{ + return (a != b) & ((a | b) == 0); +} + +int f4(int a, int b) +{ + return (a == b) | ((a | b) != 0); +} + +/* { dg-final { scan-tree-dump-times "\\\|" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\&" 0 "optimized" } } */ + +/* f3 should fold to `1` (true). */ +/* { dg-final { scan-tree-dump-times "return 1;" 1 "optimized" } } */ + +/* f4 should fold to `0` (false). */ +/* { dg-final { scan-tree-dump-times "return 0;" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/int-bwise-opt-2.c b/gcc/testsuite/gcc.dg/int-bwise-opt-2.c new file mode 100644 index 00000000000..cc1a48b061a --- /dev/null +++ b/gcc/testsuite/gcc.dg/int-bwise-opt-2.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int f1(int a, int b) +{ + return (a != b) | ((a | b) != 0); +} + +int f2(int a, int b) +{ + return (a == b) & ((a | b) == 0); +} + + /* { dg-final { scan-tree-dump-times "a == b" 0 "optimized" } } */ + /* { dg-final { scan-tree-dump-times "a != b" 0 "optimized" } } */ -- 2.47.3