MATCH: Fix patterns of type (a != b) and (a == b) [PR117760]

Message ID 20250415062451.21409-1-quic_eikagupt@quicinc.com
State New
Headers
Series MATCH: Fix patterns of type (a != b) and (a == b) [PR117760] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed

Commit Message

Eikansh Gupta April 15, 2025, 6:24 a.m. UTC
  The patterns can be simplified as shown below:

(a != b) & ((a|b) != 0)  -> (a != b)
(a != b) | ((a|b) != 0)  -> ((a|b) != 0)

The similar simplification can be there for (a == b). This patch adds
simplification for above patterns. The forwprop pass was modifying the
patterns to some other form and they were not getting simplified. The
patch also adds simplification for those patterns.

Bootstrapped and tested on x86_64-linux-gnu with no regressions.

	PR 117760

gcc/ChangeLog:

	* match.pd ((a != b) and/or ((a | b) != 0)): New pattern.
  ((a == b) and/or (a | b) == 0): New pattern.
  ((a == b) & (a | b) == 0): New pattern.

gcc/testsuite/ChangeLog:

	* gcc.dg/tree-ssa/pr117760-1.c: New test.
	* gcc.dg/tree-ssa/pr117760-2.c: New test.
	* gcc.dg/tree-ssa/pr117760.c: New test.

Signed-off-by: Eikansh Gupta <quic_eikagupt@quicinc.com>
---
 gcc/match.pd                               | 58 ++++++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr117760-1.c | 51 +++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr117760-2.c | 37 ++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr117760.c   | 51 +++++++++++++++++++
 4 files changed, 197 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr117760-1.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr117760-2.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr117760.c
  

Comments

Jeff Law April 15, 2025, 3:16 p.m. UTC | #1
On 4/15/25 12:24 AM, Eikansh Gupta wrote:
> The patterns can be simplified as shown below:
> 
> (a != b) & ((a|b) != 0)  -> (a != b)
> (a != b) | ((a|b) != 0)  -> ((a|b) != 0)
> 
> The similar simplification can be there for (a == b). This patch adds
> simplification for above patterns. The forwprop pass was modifying the
> patterns to some other form and they were not getting simplified. The
> patch also adds simplification for those patterns.
> 
> Bootstrapped and tested on x86_64-linux-gnu with no regressions.
> 
> 	PR 117760
> 
> gcc/ChangeLog:
> 
> 	* match.pd ((a != b) and/or ((a | b) != 0)): New pattern.
>    ((a == b) and/or (a | b) == 0): New pattern.
>    ((a == b) & (a | b) == 0): New pattern.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.dg/tree-ssa/pr117760-1.c: New test.
> 	* gcc.dg/tree-ssa/pr117760-2.c: New test.
> 	* gcc.dg/tree-ssa/pr117760.c: New test.
Deferring to gcc-16 stage1.

jeff
  

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index 5c679848bdf..291c08d5882 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4852,6 +4852,64 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	&& expr_no_side_effects_p (@1))
    @2)))
 
+(for cmp (eq ne)
+ (for bitop (bit_ior bit_and)
+  /* ((a != b) & ((a | b) != 0)) -> (a != b) */
+  /* ((a != b) | ((a | b) != 0)) -> ((a|b) != 0) */
+  /* ((a == b) & (a | b) == 0) -> ((a|b) == 0) */
+  /* ((a == b) | (a | b) == 0) -> (a == b) */
+  (simplify
+   (bitop:c
+    (cmp@3 @1 @2)
+     (cmp@4 (bit_ior @1 @2) integer_zerop))
+   (if ((cmp == EQ_EXPR) ^ (bitop == BIT_IOR_EXPR))
+    @4 @3))
+
+  /* ((a == b) | (a == 0) | (b == 0)) -> (a == b) */
+  /* ((a == b) & ((a == 0) | (b == 0))) -> ((a|b) == 0) */
+  (simplify
+   (bitop:c
+    (eq:c@3 @1 @2)
+     (bit_ior (eq @1 integer_zerop) (eq @2 integer_zerop)))
+   (if (bitop == BIT_IOR_EXPR)
+    @3 (eq (bit_ior @1 @2) { build_zero_cst (TREE_TYPE (@1)); }))))
+
+  /* (((a == b) & (a == 0)) | (b == 0)) -> ((a|b) == 0) */
+  /* (((a != b) & (a != 0)) | (b != 0)) -> (a != b) */
+  (simplify
+   (bit_ior:c (bit_and (cmp @1 integer_zerop) (cmp:c @1 @2))
+    (cmp @2 integer_zerop))
+   (if (cmp == EQ_EXPR)
+    (eq (bit_ior @1 @2) { build_zero_cst (TREE_TYPE (@1)); })
+     (ne @1 @2))))
+
+/* ((a != b) | (a != 0) | (b != 0)) -> ((a|b) != 0) */
+(simplify
+ (bit_ior:c
+  (ne @1 @2)
+   (bit_ior:c (ne @1 integer_zerop) (ne @2 integer_zerop)))
+ (ne (bit_ior @1 @2) { build_zero_cst (TREE_TYPE (@1)); }))
+
+/* ((a != b) & ((a | b) == 0)) -> false */
+(simplify
+ (bit_and:c
+  (ne @1 @2)
+   (eq (bit_ior @1 @2) integer_zerop))
+ { constant_boolean_node (false, type); })
+
+/* ((a != b) & ((a == 0) | (b == 0))) -> false */
+(simplify
+ (bit_and:c
+  (ne:c@3 @1 @2)
+   (bit_ior:c (eq @1 integer_zerop) (eq @2 integer_zerop)))
+ { constant_boolean_node (false, type); })
+
+/* (((a != b) & (a == 0)) | (b == 0)) -> false */
+(simplify
+ (bit_ior:c (bit_and:c (eq @1 integer_zerop) (ne:c @1 @2))
+  (eq @2 integer_zerop))
+ { constant_boolean_node (false, type); })
+
 /* Simplifications of shift and rotates.  */
 
 (for rotate (lrotate rrotate)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr117760-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr117760-1.c
new file mode 100644
index 00000000000..94a05f20ff0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr117760-1.c
@@ -0,0 +1,51 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized-raw" } */
+
+int f1(int a, int b)
+{
+  if (a == 0 || b == 0)
+    return a == b;
+  return 0;
+}
+
+int f2(int a, int b)
+{
+  int c = a == 0;
+  int d = b == 0;
+  int e = a == b;
+  return c|d|e;
+}
+
+int f3(int a, int b)
+{
+  int c = a == 0;
+  int d = b == 0;
+  int e = a == b;
+  return (c|d)&e;
+}
+
+int f4(int a, int b)
+{
+  int c = a == 0;
+  int d = b == 0;
+  int e = a == b;
+  return c|d&e;
+}
+
+int f5(int a, int b)
+{
+  int c = (a|b) == 0;
+  int e = a == b;
+  return c|e;
+}
+
+int f6(int a, int b)
+{
+  int c = (a|b) == 0;
+  int e = a == b;
+  return c&e;
+}
+
+/* { dg-final { scan-tree-dump-times "eq_expr, " 6 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "nop_expr, " 6 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "bit_ior_expr, " 4 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr117760-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr117760-2.c
new file mode 100644
index 00000000000..62c147cd6a4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr117760-2.c
@@ -0,0 +1,37 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized-raw" } */
+
+int f1(int a, int b)
+{
+  int c = a == 0;
+  int d = b == 0;
+  int e = a != b;
+  return (c|d)&e;
+}
+
+int f2(int a, int b)
+{
+  int c = (a|b) == 0;
+  int e = a != b;
+  return c&e;
+}
+
+int f3(int a, int b)
+{
+  int c = a == 0;
+  int d = b == 0;
+  int e = a != b;
+  return c|d&e;
+}
+
+int f4(int a, int b)
+{
+  if (a == 0 || b == 0)
+    return a != b;
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "ne_expr," "optimized"  } } */
+/* { dg-final { scan-tree-dump-not "eq_expr," "optimized"  } } */
+/* { dg-final { scan-tree-dump-not "bit_ior_expr," "optimized"  } } */
+/* { dg-final { scan-tree-dump-not "bit_and_expr," "optimized"  } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr117760.c b/gcc/testsuite/gcc.dg/tree-ssa/pr117760.c
new file mode 100644
index 00000000000..c5f5dbd6123
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr117760.c
@@ -0,0 +1,51 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized-raw" } */
+
+int f1(int a, int b)
+{
+  if (a != 0 || b != 0)
+    return a != b;
+  return 0;
+}
+
+int f2(int a, int b)
+{
+  int c = a != 0;
+  int d = b != 0;
+  int e = a != b;
+  return c|d|e;
+}
+
+int f3(int a, int b)
+{
+  int c = a != 0;
+  int d = b != 0;
+  int e = a != b;
+  return (c|d)&e;
+}
+
+int f4(int a, int b)
+{
+  int c = a != 0;
+  int d = b != 0;
+  int e = a != b;
+  return c|d&e;
+}
+
+int f5(int a, int b)
+{
+  int c = (a|b) != 0;
+  int e = a != b;
+  return c|e;
+}
+
+int f6(int a, int b)
+{
+  int c = (a|b) != 0;
+  int e = a != b;
+  return c&e;
+}
+
+/* { dg-final { scan-tree-dump-times "ne_expr, " 6 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "nop_expr, " 6 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "bit_ior_expr, " 2 "optimized" } } */