]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH][PR tree-optimization/117760] `a != b` implies that a or b is also non-zero
authorMatteo Nicoli <matteo.nicoli001@gmail.com>
Sat, 4 Oct 2025 15:22:54 +0000 (09:22 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Sat, 4 Oct 2025 15:27:57 +0000 (09:27 -0600)
Implements a match.pd pattern to optimize the cases found in PR 117760.

PR tree-optimization/117760
gcc/
* match.pd: Add simplifications that exploit implied values after
logical tests.

gcc/testsuite
* gcc.dg/int-bwise-opt-1.c: New test.
* gcc.dg/int-bwise-opt-2.c: New test.

gcc/match.pd
gcc/testsuite/gcc.dg/int-bwise-opt-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/int-bwise-opt-2.c [new file with mode: 0644]

index b3fd26e18dddc9a7aa13aba725afa84b7b247418..6f896aa7961cf4193af04ff45d2ce539b3cb37c6 100644 (file)
@@ -6808,6 +6808,34 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    @2))
 )
 
+#if GIMPLE
+/* Given two integers a and b:
+   (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)
+   (a != b) & ((a|b) == 0) -> false
+   (a == b) | ((a|b) != 0) -> true  */
+(simplify
+ (bit_and:c (ne:c @0 @1) (ne (bit_ior @0 @1) integer_zerop))
+ (ne @0 @1))
+(simplify
+ (bit_ior:c (ne:c @0 @1) (ne (bit_ior @0 @1) integer_zerop))
+ (ne (bit_ior @0 @1) { integer_zero_node; }))
+(simplify
+ (bit_and:c (eq:c @0 @1) (eq (bit_ior @0 @1) integer_zerop))
+ (eq (bit_ior @0 @1) { integer_zero_node; }))
+(simplify
+ (bit_ior:c (eq:c @0 @1) (eq (bit_ior @0 @1) integer_zerop))
+ (eq @0 @1))
+(simplify
+ (bit_and:c (ne:c @0 @1) (eq (bit_ior @0 @1) integer_zerop))
+ { build_zero_cst (type); })
+(simplify
+ (bit_ior:c (eq:c @0 @1) (ne (bit_ior @0 @1) integer_zerop))
+ { build_one_cst (type); })
+#endif
+
 /* These was part of minmax phiopt.  */
 /* Optimize (a CMP b) ? minmax<a, c> : minmax<b, c>
    to minmax<min/max<a, b>, c> */
diff --git a/gcc/testsuite/gcc.dg/int-bwise-opt-1.c b/gcc/testsuite/gcc.dg/int-bwise-opt-1.c
new file mode 100644 (file)
index 0000000..11ea9ac
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int f1(int a, int b)
+{
+  return (a != b) & ((a | b) != 0);
+}
+
+int f2(int a, int b)
+{
+  return (a == b) | ((a | b) == 0);
+}
+
+int f3(int a, int b)
+{
+  return (a != b) & ((a | b) == 0);
+}
+
+int f4(int a, int b)
+{
+  return (a == b) | ((a | b) != 0);
+}
+
+/* { dg-final { scan-tree-dump-times "\\\|" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\&" 0 "optimized" } } */
+
+/* f3 should fold to `1` (true).  */
+/* { dg-final { scan-tree-dump-times "return 1;" 1 "optimized" } } */
+
+/* f4 should fold to `0` (false).  */
+/* { dg-final { scan-tree-dump-times "return 0;" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/int-bwise-opt-2.c b/gcc/testsuite/gcc.dg/int-bwise-opt-2.c
new file mode 100644 (file)
index 0000000..cc1a48b
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int f1(int a, int b)
+{
+  return (a != b) | ((a | b) != 0);
+}
+
+int f2(int a, int b)
+{
+  return (a == b) & ((a | b) == 0);
+}
+
+ /* { dg-final { scan-tree-dump-times "a == b" 0 "optimized" } } */
+ /* { dg-final { scan-tree-dump-times "a != b" 0 "optimized" } } */