The patch adds the following simplification pattern.
(a == b) & (a == c) & (b != c) -> false
Bootstrapped and tested on x86_64-linux-gnu and aarch64-linux-gnu.
PR tree-optimization/110922
gcc/ChangeLog:
* match.pd ((a==b)&(a==c)&(b!=c)): New Pattern.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/pr110922.c: New test.
Signed-off-by: Pengxuan Zheng <[email protected]>
---
gcc/match.pd | 12 +++
gcc/testsuite/gcc.dg/tree-ssa/pr110922.c | 100 +++++++++++++++++++++++
2 files changed, 112 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr110922.c
diff --git a/gcc/match.pd b/gcc/match.pd
index b037b1a2876..e6552c4e868 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6643,6 +6643,18 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(simplify
(bitop (neeql @0 @1) (neeqr (bit_ior @0 @1) integer_zerop))
{ constant_boolean_node (bitop == BIT_IOR_EXPR, type); }))
+
+/* (a == b) & (a == c) & (b != c) -> false */
+(simplify
+ (bit_and:c
+ (bit_and:c (eq:c @0 @1) (eq:c @0 @2))
+ (ne:c @1 @2))
+ { constant_boolean_node (false, type); })
+(simplify
+ (bit_and:c
+ (bit_and:c (eq:c @0 @1) (ne:c @1 @2))
+ (eq:c @0 @2))
+ { constant_boolean_node (false, type); })
#endif
/* These was part of minmax phiopt. */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110922.c
b/gcc/testsuite/gcc.dg/tree-ssa/pr110922.c
new file mode 100644
index 00000000000..353c99bbc2d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110922.c
@@ -0,0 +1,100 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int f1(int a, int b, int c)
+{
+ _Bool t = a == b;
+ _Bool t1 = a == c;
+ _Bool t2 = b != c;
+ return t&t1&t2;
+}
+
+int f2(int a, int b, int c)
+{
+ _Bool t = a == b;
+ _Bool t1 = a == c;
+ _Bool t2 = b != c;
+ return t1&t&t2;
+}
+
+int f3(int a, int b, int c)
+{
+ _Bool t = a == b;
+ _Bool t1 = a == c;
+ _Bool t2 = b != c;
+ return t2&(t&t1);
+}
+
+int f4(int a, int b, int c)
+{
+ _Bool t = a == b;
+ _Bool t1 = a == c;
+ _Bool t2 = b != c;
+ return t2&(t1&t);
+}
+
+int f5(int a, int b, int c)
+{
+ _Bool t = a == b;
+ _Bool t1 = a == c;
+ _Bool t2 = b != c;
+ return t&t2&t1;
+}
+
+int f6(int a, int b, int c)
+{
+ _Bool t = a == b;
+ _Bool t1 = a == c;
+ _Bool t2 = b != c;
+ return t2&t&t1;
+}
+
+int f7(int a, int b, int c)
+{
+ _Bool t = a == b;
+ _Bool t1 = a == c;
+ _Bool t2 = b != c;
+ return t2&(t&t1);
+}
+
+int f8(int a, int b, int c)
+{
+ _Bool t = a == b;
+ _Bool t1 = a == c;
+ _Bool t2 = b != c;
+ return t2&(t1&t);
+}
+
+int f9(int a, int b)
+{
+ _Bool t = a == b;
+ _Bool t1 = a == 0;
+ _Bool t2 = b != 0;
+ return t&(t1&t2);
+}
+
+int f10(int a, int b)
+{
+ _Bool t = a == b;
+ _Bool t1 = a == 0;
+ _Bool t2 = b != 0;
+ return t&(t2&t1);
+}
+
+int f11(int a, int b)
+{
+ _Bool t = a == b;
+ _Bool t1 = a == 0;
+ _Bool t2 = b != 0;
+ return (t1&t2)&t;
+}
+
+int f12(int a, int b)
+{
+ _Bool t = a == b;
+ _Bool t1 = a == 0;
+ _Bool t2 = b != 0;
+ return (t2&t1)&t;
+}
+
+/* { dg-final { scan-tree-dump-times "return 0;" 12 "optimized" } } */
--
2.34.1