https://gcc.gnu.org/g:0621cf67366ffa2215cdd081b1ca1c3c577e8b70
commit r17-3166-g0621cf67366ffa2215cdd081b1ca1c3c577e8b70 Author: Kael Andrew Alonzo Franco <[email protected]> Date: Sat Aug 8 22:04:12 2026 -0400 middle-end: Wrong code for a != b | (a|b) != 0. [PR126742] Since r17-2886, GCC does a wrong optimize with: (a == b) & ((a|b) == 0) -> ((a|b) != 0) (a != b) | ((a|b) != 0) -> ((a|b) == 0) Should be: (a == b) & ((a|b) == 0) -> ((a|b) == 0) (a != b) | ((a|b) != 0) -> ((a|b) != 0) Regtest missed this because gcc.dg/int-bwise-opt-2.c only test: /* { dg-final { scan-tree-dump-times "a == b" 0 "optimized" } } */ /* { dg-final { scan-tree-dump-times "a != b" 0 "optimized" } } */ Make this test more rigorous by comparing the final code. Bootstrapped and regtested on x86_64-pc-linux-gnu. PR middle-end/126742 gcc/ChangeLog: * match.pd: Fix wrong code. gcc/testsuite/ChangeLog: * gcc.dg/int-bwise-opt-2.c: Also test for PR126742. Signed-off-by: Kael Andrew Franco <[email protected]> Diff: --- gcc/match.pd | 2 +- gcc/testsuite/gcc.dg/int-bwise-opt-2.c | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index c2f411001a03..efaf0026711c 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -7037,7 +7037,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (neeq @0 @1)) (simplify (bitop:c (eqne @0 @1) (eqne (bit_ior@2 @0 @1) integer_zerop@3)) - (neeq @2 @3)) + (eqne @2 @3)) (simplify (bitop (neeq @0 @1) (eqne (bit_ior @0 @1) integer_zerop)) { constant_boolean_node (bitop == BIT_IOR_EXPR, type); }) diff --git a/gcc/testsuite/gcc.dg/int-bwise-opt-2.c b/gcc/testsuite/gcc.dg/int-bwise-opt-2.c index cc1a48b061a2..e0c065a54f36 100644 --- a/gcc/testsuite/gcc.dg/int-bwise-opt-2.c +++ b/gcc/testsuite/gcc.dg/int-bwise-opt-2.c @@ -1,15 +1,18 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fdump-tree-optimized" } */ -int f1(int a, int b) +_Bool +a_ne_b_bit_ior (int a, int b) { - return (a != b) | ((a | b) != 0); + _Bool ret = ((a | b) != 0); + return (((a != b) | ret) == ret); } -int f2(int a, int b) +_Bool +a_eq_b_bit_and (int a, int b) { - return (a == b) & ((a | b) == 0); + _Bool ret = ((a | b) == 0); + return (((a == b) & ret) == ret); } - /* { dg-final { scan-tree-dump-times "a == b" 0 "optimized" } } */ - /* { dg-final { scan-tree-dump-times "a != b" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "return 1;" 2 "optimized" } } */
