diff mbox series

match.pd: Optimize (x < 0) != (y < 0) into (x ^ y) < 0 [PR94718]

Message ID 20200430130538.GW2424@tucnak
State New
Headers show
Series match.pd: Optimize (x < 0) != (y < 0) into (x ^ y) < 0 [PR94718] | expand

Commit Message

Jakub Jelinek April 30, 2020, 1:05 p.m. UTC
Hi!

The following patch (on top of the two other PR94718 patches) performs the
actual optimization requested in the PR.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for stage1?

2020-04-30  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/94718
	* match.pd ((X < 0) != (Y < 0) into (X ^ Y) < 0): New simplification.

	* gcc.dg/tree-ssa/pr94718-4.c: New test.
	* gcc.dg/tree-ssa/pr94718-5.c: New test.


	Jakub

Comments

Richard Biener April 30, 2020, 1:11 p.m. UTC | #1
On Thu, 30 Apr 2020, Jakub Jelinek wrote:

> Hi!
> 
> The following patch (on top of the two other PR94718 patches) performs the
> actual optimization requested in the PR.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for stage1?
> 
> 2020-04-30  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR tree-optimization/94718
> 	* match.pd ((X < 0) != (Y < 0) into (X ^ Y) < 0): New simplification.
> 
> 	* gcc.dg/tree-ssa/pr94718-4.c: New test.
> 	* gcc.dg/tree-ssa/pr94718-5.c: New test.
> 
> --- gcc/match.pd.jj	2020-04-30 12:43:10.473982154 +0200
> +++ gcc/match.pd	2020-04-30 13:10:11.305134082 +0200
> @@ -4358,6 +4358,28 @@ (define_operator_list COND_TERNARY
>    (cmp (bit_and:cs @0 @2) (bit_and:cs @1 @2))
>    (cmp (bit_and (bit_xor @0 @1) @2) { build_zero_cst (TREE_TYPE (@2)); })))
>  
> +/* (X < 0) != (Y < 0) into (X ^ Y) < 0.
> +   (X >= 0) != (Y >= 0) into (X ^ Y) < 0.
> +   (X < 0) == (Y < 0) into (X ^ Y) >= 0.
> +   (X >= 0) == (Y >= 0) into (X ^ Y) >= 0.  */
> +(for cmp (eq ne)
> +     ncmp (ge lt)
> + (for sgncmp (ge lt)
> +  (simplify
> +   (cmp (sgncmp @0 integer_zerop@2) (sgncmp @1 integer_zerop))
> +   (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
> +	&& !TYPE_UNSIGNED (TREE_TYPE (@0))
> +	&& types_match (@0, @1))
> +    (ncmp (bit_xor @0 @1) @2)))))

Can you also add a comment for the ones below?  OK with that change.

> +(for cmp (eq ne)
> +     ncmp (lt ge)
> + (simplify
> +  (cmp:c (lt @0 integer_zerop@2) (ge @1 integer_zerop))
> +   (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
> +	&& !TYPE_UNSIGNED (TREE_TYPE (@0))
> +	&& types_match (@0, @1))
> +    (ncmp (bit_xor @0 @1) @2))))
> +
>  /* If we have (A & C) == C where C is a power of 2, convert this into
>     (A & C) != 0.  Similarly for NE_EXPR.  */
>  (for cmp (eq ne)
> --- gcc/testsuite/gcc.dg/tree-ssa/pr94718-4.c.jj	2020-04-30 12:56:00.552606387 +0200
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr94718-4.c	2020-04-30 13:12:57.320699373 +0200
> @@ -0,0 +1,61 @@
> +/* PR tree-optimization/94718 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */
> +/* { dg-final { scan-tree-dump-times "= \[xy]_\[0-9]+\\\(D\\\) \\^ \[xy]_\[0-9]+\\\(D\\\);" 8 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "\[0-9]+ < 0;" 8 "optimized" } } */
> +
> +int
> +f1 (int x, int y)
> +{
> +  return (x < 0) != (y < 0);
> +}
> +
> +int
> +f2 (int x, int y)
> +{
> +  return (x >= 0) != (y >= 0);
> +}
> +
> +int
> +f3 (int x, int y)
> +{
> +  return (x < 0) == (y >= 0);
> +}
> +
> +int
> +f4 (int x, int y)
> +{
> +  return (x >= 0) == (y < 0);
> +}
> +
> +int
> +f5 (int x, int y)
> +{
> +  int s = (x < 0);
> +  int t = (y < 0);
> +  return s != t;
> +}
> +
> +int
> +f6 (int x, int y)
> +{
> +  int s = (x >= 0);
> +  int t = (y >= 0);
> +  return s != t;
> +}
> +
> +int
> +f7 (int x, int y)
> +{
> +  int s = (x < 0);
> +  int t = (y >= 0);
> +  return s == t;
> +}
> +
> +int
> +f8 (int x, int y)
> +{
> +  int s = (x >= 0);
> +  int t = (y < 0);
> +  return s == t;
> +}
> --- gcc/testsuite/gcc.dg/tree-ssa/pr94718-5.c.jj	2020-04-30 13:01:44.893558240 +0200
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr94718-5.c	2020-04-30 13:14:00.434768470 +0200
> @@ -0,0 +1,61 @@
> +/* PR tree-optimization/94718 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */
> +/* { dg-final { scan-tree-dump-times "= \[xy]_\[0-9]+\\\(D\\\) \\^ \[xy]_\[0-9]+\\\(D\\\);" 8 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "\[0-9]+ >= 0;" 8 "optimized" } } */
> +
> +int
> +f1 (int x, int y)
> +{
> +  return (x < 0) == (y < 0);
> +}
> +
> +int
> +f2 (int x, int y)
> +{
> +  return (x >= 0) == (y >= 0);
> +}
> +
> +int
> +f3 (int x, int y)
> +{
> +  return (x < 0) != (y >= 0);
> +}
> +
> +int
> +f4 (int x, int y)
> +{
> +  return (x >= 0) != (y < 0);
> +}
> +
> +int
> +f5 (int x, int y)
> +{
> +  int s = (x < 0);
> +  int t = (y < 0);
> +  return s == t;
> +}
> +
> +int
> +f6 (int x, int y)
> +{
> +  int s = (x >= 0);
> +  int t = (y >= 0);
> +  return s == t;
> +}
> +
> +int
> +f7 (int x, int y)
> +{
> +  int s = (x < 0);
> +  int t = (y >= 0);
> +  return s != t;
> +}
> +
> +int
> +f8 (int x, int y)
> +{
> +  int s = (x >= 0);
> +  int t = (y < 0);
> +  return s != t;
> +}
> 
> 	Jakub
> 
>
diff mbox series

Patch

--- gcc/match.pd.jj	2020-04-30 12:43:10.473982154 +0200
+++ gcc/match.pd	2020-04-30 13:10:11.305134082 +0200
@@ -4358,6 +4358,28 @@  (define_operator_list COND_TERNARY
   (cmp (bit_and:cs @0 @2) (bit_and:cs @1 @2))
   (cmp (bit_and (bit_xor @0 @1) @2) { build_zero_cst (TREE_TYPE (@2)); })))
 
+/* (X < 0) != (Y < 0) into (X ^ Y) < 0.
+   (X >= 0) != (Y >= 0) into (X ^ Y) < 0.
+   (X < 0) == (Y < 0) into (X ^ Y) >= 0.
+   (X >= 0) == (Y >= 0) into (X ^ Y) >= 0.  */
+(for cmp (eq ne)
+     ncmp (ge lt)
+ (for sgncmp (ge lt)
+  (simplify
+   (cmp (sgncmp @0 integer_zerop@2) (sgncmp @1 integer_zerop))
+   (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+	&& !TYPE_UNSIGNED (TREE_TYPE (@0))
+	&& types_match (@0, @1))
+    (ncmp (bit_xor @0 @1) @2)))))
+(for cmp (eq ne)
+     ncmp (lt ge)
+ (simplify
+  (cmp:c (lt @0 integer_zerop@2) (ge @1 integer_zerop))
+   (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+	&& !TYPE_UNSIGNED (TREE_TYPE (@0))
+	&& types_match (@0, @1))
+    (ncmp (bit_xor @0 @1) @2))))
+
 /* If we have (A & C) == C where C is a power of 2, convert this into
    (A & C) != 0.  Similarly for NE_EXPR.  */
 (for cmp (eq ne)
--- gcc/testsuite/gcc.dg/tree-ssa/pr94718-4.c.jj	2020-04-30 12:56:00.552606387 +0200
+++ gcc/testsuite/gcc.dg/tree-ssa/pr94718-4.c	2020-04-30 13:12:57.320699373 +0200
@@ -0,0 +1,61 @@ 
+/* PR tree-optimization/94718 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "= \[xy]_\[0-9]+\\\(D\\\) \\^ \[xy]_\[0-9]+\\\(D\\\);" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\[0-9]+ < 0;" 8 "optimized" } } */
+
+int
+f1 (int x, int y)
+{
+  return (x < 0) != (y < 0);
+}
+
+int
+f2 (int x, int y)
+{
+  return (x >= 0) != (y >= 0);
+}
+
+int
+f3 (int x, int y)
+{
+  return (x < 0) == (y >= 0);
+}
+
+int
+f4 (int x, int y)
+{
+  return (x >= 0) == (y < 0);
+}
+
+int
+f5 (int x, int y)
+{
+  int s = (x < 0);
+  int t = (y < 0);
+  return s != t;
+}
+
+int
+f6 (int x, int y)
+{
+  int s = (x >= 0);
+  int t = (y >= 0);
+  return s != t;
+}
+
+int
+f7 (int x, int y)
+{
+  int s = (x < 0);
+  int t = (y >= 0);
+  return s == t;
+}
+
+int
+f8 (int x, int y)
+{
+  int s = (x >= 0);
+  int t = (y < 0);
+  return s == t;
+}
--- gcc/testsuite/gcc.dg/tree-ssa/pr94718-5.c.jj	2020-04-30 13:01:44.893558240 +0200
+++ gcc/testsuite/gcc.dg/tree-ssa/pr94718-5.c	2020-04-30 13:14:00.434768470 +0200
@@ -0,0 +1,61 @@ 
+/* PR tree-optimization/94718 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "= \[xy]_\[0-9]+\\\(D\\\) \\^ \[xy]_\[0-9]+\\\(D\\\);" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\[0-9]+ >= 0;" 8 "optimized" } } */
+
+int
+f1 (int x, int y)
+{
+  return (x < 0) == (y < 0);
+}
+
+int
+f2 (int x, int y)
+{
+  return (x >= 0) == (y >= 0);
+}
+
+int
+f3 (int x, int y)
+{
+  return (x < 0) != (y >= 0);
+}
+
+int
+f4 (int x, int y)
+{
+  return (x >= 0) != (y < 0);
+}
+
+int
+f5 (int x, int y)
+{
+  int s = (x < 0);
+  int t = (y < 0);
+  return s == t;
+}
+
+int
+f6 (int x, int y)
+{
+  int s = (x >= 0);
+  int t = (y >= 0);
+  return s == t;
+}
+
+int
+f7 (int x, int y)
+{
+  int s = (x < 0);
+  int t = (y >= 0);
+  return s != t;
+}
+
+int
+f8 (int x, int y)
+{
+  int s = (x >= 0);
+  int t = (y < 0);
+  return s != t;
+}