PR tree-optimization/92342: Optimize b & -(a==c) in match.pd
authorRoger Sayle <roger@nextmovesoftware.com>
Thu, 12 Jan 2023 21:47:40 +0000 (21:47 +0000)
committerRoger Sayle <roger@nextmovesoftware.com>
Thu, 12 Jan 2023 21:48:50 +0000 (21:48 +0000)
This patch is an update/tweak of Andrew Pinski's two patches for
PR tree-optimization/92342, that were originally posted by in November:
https://gcc.gnu.org/pipermail/gcc-patches/2021-November/585111.html
https://gcc.gnu.org/pipermail/gcc-patches/2021-November/585112.html

Technically, the first of those was approved by Richard Biener, though
never committed, and my first thought was to simply push it for Andrew,
but the review of the second piece expressed concerns over comparisons
in non-integral modes, where the result may not be zero-one valued.
Indeed both transformations misbehave in the presence of vector mode
comparisons (these transformations are already implemented for
vec_cond elsewhere in match.pd), so my minor contribution is to limit
these new transformations to scalars, by testing that both the operands
and results are INTEGRAL_TYPE_P.

2023-01-12  Andrew Pinski  <apinski@marvell.com>
    Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog:
PR tree-optimization/92342
* match.pd ((m1 CMP m2) * d -> (m1 CMP m2) ? d : 0):
Use tcc_comparison and :c for the multiply.
(b & -(a CMP c) -> (a CMP c)?b:0): New pattern.

gcc/testsuite/ChangeLog:
PR tree-optimization/92342
* gcc.dg/tree-ssa/andnegcmp-1.c: New test.
* gcc.dg/tree-ssa/andnegcmp-2.c: New test.
* gcc.dg/tree-ssa/multcmp-1.c: New test.
* gcc.dg/tree-ssa/multcmp-2.c: New test.

gcc/match.pd
gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/multcmp-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/multcmp-2.c [new file with mode: 0644]

index d160156..56ac743 100644 (file)
@@ -2076,10 +2076,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 
 /* (m1 CMP m2) * d -> (m1 CMP m2) ? d : 0  */
 (if (!canonicalize_math_p ())
- (for cmp (gt lt ge le)
+ (for cmp (tcc_comparison)
   (simplify
-   (mult (convert (cmp @0 @1)) @2)
-   (cond (cmp @0 @1) @2 { build_zero_cst (type); }))))
+   (mult:c (convert (cmp@0 @1 @2)) @3)
+   (if (INTEGRAL_TYPE_P (type)
+       && INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+     (cond @0 @3 { build_zero_cst (type); })))
+/* (-(m1 CMP m2)) & d -> (m1 CMP m2) ? d : 0  */
+  (simplify
+   (bit_and:c (negate (convert (cmp@0 @1 @2))) @3)
+   (if (INTEGRAL_TYPE_P (type)
+       && INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+     (cond @0 @3 { 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 (file)
index 0000000..6f16783
--- /dev/null
@@ -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 (file)
index 0000000..0e25c8a
--- /dev/null
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/multcmp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/multcmp-1.c
new file mode 100644 (file)
index 0000000..fb44cac
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int
+f (int m1, int m2, int c)
+{
+  int d = m1 == m2;
+  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/multcmp-2.c b/gcc/testsuite/gcc.dg/tree-ssa/multcmp-2.c
new file mode 100644 (file)
index 0000000..be38b2e
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int
+f (int m1, int m2, int c)
+{
+  int d = m1 != m2;
+  int e = c * d;
+  return e;
+}
+
+/* { dg-final { scan-tree-dump-times "\\? c_\[0-9\]\\(D\\) : 0" 1 "optimized" } } */