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.
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
--- /dev/null
+// { 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