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
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
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
@@ -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)
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */
new file mode 100644
@@ -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" } } */