https://gcc.gnu.org/g:7b2e9d01d325f091ab7615985f413dda78415fec
commit r16-7367-g7b2e9d01d325f091ab7615985f413dda78415fec Author: Daniel Barboza <[email protected]> Date: Fri Jan 23 13:10:30 2026 -0300 match.pd: (A | (convert?)(A != 0)) EQ|NE 0 -> A EQ|NE 0 [PR114969] The NE variant is a gimple pattern that comes from the following C++ code: bool result = (std::max( (unsigned long long) 0, (unsigned long long) var_0)) | ( var_0 ? 1 : 0); PR tree-optimization/114969 gcc/ChangeLog: * match.pd (`(A | (convert?)(A != 0)) EQ|NE 0`): New pattern. gcc/testsuite/ChangeLog: * g++.dg/pr114969.C: New test. Diff: --- gcc/match.pd | 10 ++++++++++ gcc/testsuite/g++.dg/pr114969.C | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/gcc/match.pd b/gcc/match.pd index f4732d39c517..8910591a04b3 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -8368,6 +8368,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) sign extension followed by AND with C will achieve the effect. */ (bit_and (convert @0) @1))))) +/* (A | (convert?)(A != 0)) EQ|NE 0 -> A EQ|NE 0 (PR114969) + + The NE variant of this pattern is produced by the C++ code: + + (bool)(std::max (ulong_A, 0) | (ulong_A ? 1 : 0)). */ +(for cmp (eq ne) + (simplify + (cmp (bit_ior:c @0 (convert? (ne @0 integer_zerop))) integer_zerop) + (cmp @0 { build_zero_cst (TREE_TYPE (@0)); }))) + /* When the addresses are not directly of decls compare base and offset. This implements some remaining parts of fold_comparison address comparisons but still no complete part of it. Still it is good diff --git a/gcc/testsuite/g++.dg/pr114969.C b/gcc/testsuite/g++.dg/pr114969.C new file mode 100644 index 000000000000..4eca335ee426 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr114969.C @@ -0,0 +1,16 @@ +// { dg-do compile { target c++17 } } +// { dg-options "-O3 -fdump-tree-optimized" } + +#include <algorithm> + +bool result; + +void func (unsigned long long var_0) { + result = (std::max ((unsigned long long) 0, (unsigned long long) var_0)) | ( var_0 ? 1 : 0); +} + +void func2 (unsigned long long var_0) { + result = !((std::max ((unsigned long long) 0, (unsigned long long) var_0)) | ( var_0 ? 1 : 0)); +} + +/* { dg-final { scan-tree-dump-times " \\\| " 0 "optimized" } } */ \ No newline at end of file
