https://gcc.gnu.org/g:5e933bd275f0e6eef18692ef351cb5d617f48d51
commit r17-418-g5e933bd275f0e6eef18692ef351cb5d617f48d51 Author: Andrew Pinski <[email protected]> Date: Fri May 8 12:46:32 2026 -0700 match: Fix merged patterns for a!=b implies a and b are not zero [PR125234] In r17-231-gc65691bc5a2873, I messed up the resulting constant for `(a != b) & ((a | b) == 0)` and `(a == b) | ((a | b) != 0)`. I had swapped which one was resulting in true/false. This fixes the issue and adds a testcase to make sure it does not regress again. Pushed as obvious after a bootstrap/test on x86_64-linux-gnu. PR tree-optimization/125234 gcc/ChangeLog: * match.pd (`(a !=/== b) &\| ((a|b) ==/!= 0)`): Fix resulting constant form. gcc/testsuite/ChangeLog: * gcc.dg/torture/pr125234-1.c: New test. Signed-off-by: Andrew Pinski <[email protected]> Diff: --- gcc/match.pd | 2 +- gcc/testsuite/gcc.dg/torture/pr125234-1.c | 49 +++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/gcc/match.pd b/gcc/match.pd index 494e26a7d49a..198e2e7202e8 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -7197,7 +7197,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) neeqr (eq ne) (simplify (bitop (neeql @0 @1) (neeqr (bit_ior @0 @1) integer_zerop)) - { constant_boolean_node (bitop==BIT_AND_EXPR, type); })) + { constant_boolean_node (bitop == BIT_IOR_EXPR, type); })) #endif /* These was part of minmax phiopt. */ diff --git a/gcc/testsuite/gcc.dg/torture/pr125234-1.c b/gcc/testsuite/gcc.dg/torture/pr125234-1.c new file mode 100644 index 000000000000..70854ea8c723 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr125234-1.c @@ -0,0 +1,49 @@ +/* PR tree-optimization/125234 */ +/* { dg-do run } */ + +__attribute__((noinline)) +int f0(int a, int b) +{ + return (a != b) & ((a | b) == 0); +} + +__attribute__((noinline)) +int f1(int a, int b) +{ + return (a == b) | ((a | b) != 0); +} + + +__attribute__((noinline)) +int f0_(int a, int b) +{ + if (a != b) + if ((a | b) == 0) + return 1; + return 0; +} + +__attribute__((noinline)) +int f1_(int a, int b) +{ + if (a == b) + return 1; + if ((a | b) != 0) + return 1; + return 0; +} + + +int +main() +{ + if (f0(0, 0)) + __builtin_abort (); + if (!f1(0, 0)) + __builtin_abort (); + if (f0_(0, 0)) + __builtin_abort (); + if (!f1_(0, 0)) + __builtin_abort (); +} +
