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

Reply via email to