[2/2] tree-optimization: [PR92342] Move b & -(a==c) optimization to the gimple level

Message ID 1637562290-15155-2-git-send-email-apinski@marvell.com
State New
Headers
Series [1/2] Improve/Fix (m1 CMP m2) * d -> (m1 CMP m2) ? d : 0 pattern. |

Commit Message

Li, Pan2 via Gcc-patches Nov. 22, 2021, 6:24 a.m. UTC
  From: Andrew Pinski <apinski@marvell.com>

Combine disabled this optimization in r10-254-gddbb5da5199fb42 but it makes
sense to do this on the gimple level and then let expand decide which way is
better. So this adds the transformation on the gimple level (late like was
done for the multiply case).

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

	PR tree-optimization/92342

gcc/ChangeLog:

	* match.pd (b & -(a CMP c) -> (a CMP c)?b:0): New pattern.

gcc/testsuite/ChangeLog:

	* gcc.dg/tree-ssa/andnegcmp-1.c: New test.
	* gcc.dg/tree-ssa/andnegcmp-2.c: New test.
---
 gcc/match.pd                                |  8 +++++++-
 gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c | 14 ++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c | 14 ++++++++++++++
 3 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c
  

Comments

Richard Biener Nov. 22, 2021, 11:34 a.m. UTC | #1
On Mon, Nov 22, 2021 at 7:26 AM apinski--- via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> From: Andrew Pinski <apinski@marvell.com>
>
> Combine disabled this optimization in r10-254-gddbb5da5199fb42 but it makes
> sense to do this on the gimple level and then let expand decide which way is
> better. So this adds the transformation on the gimple level (late like was
> done for the multiply case).
>
> OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.
>
>         PR tree-optimization/92342
>
> gcc/ChangeLog:
>
>         * match.pd (b & -(a CMP c) -> (a CMP c)?b:0): New pattern.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/tree-ssa/andnegcmp-1.c: New test.
>         * gcc.dg/tree-ssa/andnegcmp-2.c: New test.
> ---
>  gcc/match.pd                                |  8 +++++++-
>  gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c | 14 ++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c | 14 ++++++++++++++
>  3 files changed, 35 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index ed43c321cbc..b55cbc91b57 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -1794,7 +1794,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>   (for cmp (tcc_comparison)
>    (simplify
>     (mult:c (convert (cmp @0 @1)) @2)
> -   (cond (cmp @0 @1) @2 { build_zero_cst (type); }))))
> +   (cond (cmp @0 @1) @2 { build_zero_cst (type); }))
> +/* (-(m1 CMP m2)) & d -> (m1 CMP m2) ? d : 0  */
> +  (simplify
> +   (bit_and:c (negate (convert (cmp @0 @1))) @2)

I think you need to guard against signed bools (and vector compares,
and allow view_convert for vector compare results?)?

> +   (cond (cmp @0 @1) @2 { build_zero_cst (type); }))
> + )
> +)
>
>  /* For integral types with undefined overflow and C != 0 fold
>     x * C EQ/NE y * C into x EQ/NE y.  */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c
> new file mode 100644
> index 00000000000..6f16783f169
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +/* PR tree-optimization/92342 */
> +
> +int
> +f (int m1, int m2, int c)
> +{
> +  int d = m1 == m2;
> +  d = -d;
> +  int e = d & c;
> +  return e;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "\\? c_\[0-9\]\\(D\\) : 0" 1 "optimized" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c b/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c
> new file mode 100644
> index 00000000000..0e25c8abc39
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +/* PR tree-optimization/92342 */
> +
> +int
> +f (int m1, int m2, int c)
> +{
> +  int d = m1 < m2;
> +  d = -d;
> +  int e = c & d;
> +  return e;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "\\? c_\[0-9\]\\(D\\) : 0" 1 "optimized" } } */
> --
> 2.17.1
>
  

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index ed43c321cbc..b55cbc91b57 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1794,7 +1794,13 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (for cmp (tcc_comparison)
   (simplify
    (mult:c (convert (cmp @0 @1)) @2)
-   (cond (cmp @0 @1) @2 { build_zero_cst (type); }))))
+   (cond (cmp @0 @1) @2 { build_zero_cst (type); }))
+/* (-(m1 CMP m2)) & d -> (m1 CMP m2) ? d : 0  */
+  (simplify
+   (bit_and:c (negate (convert (cmp @0 @1))) @2)
+   (cond (cmp @0 @1) @2 { build_zero_cst (type); }))
+ )
+)
 
 /* For integral types with undefined overflow and C != 0 fold
    x * C EQ/NE y * C into x EQ/NE y.  */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c
new file mode 100644
index 00000000000..6f16783f169
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c
@@ -0,0 +1,14 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/92342 */
+
+int
+f (int m1, int m2, int c)
+{
+  int d = m1 == m2;
+  d = -d;
+  int e = d & c;
+  return e;
+}
+
+/* { dg-final { scan-tree-dump-times "\\? c_\[0-9\]\\(D\\) : 0" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c b/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c
new file mode 100644
index 00000000000..0e25c8abc39
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c
@@ -0,0 +1,14 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/92342 */
+
+int
+f (int m1, int m2, int c)
+{
+  int d = m1 < m2;
+  d = -d;
+  int e = c & d;
+  return e;
+}
+
+/* { dg-final { scan-tree-dump-times "\\? c_\[0-9\]\\(D\\) : 0" 1 "optimized" } } */