aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-05-08 10:52:47 +0200
committerJakub Jelinek <jakub@redhat.com>2020-05-08 10:52:47 +0200
commit1595a1cb7bfac8d5a6026d5d6f3a495be0391506 (patch)
tree701be1abe1fbf79e878cf47ce6728b11606b8483 /gcc
parenta229f9b3737062c6e853879be6683f3f3e4a6661 (diff)
downloadgcc-1595a1cb7bfac8d5a6026d5d6f3a495be0391506.zip
gcc-1595a1cb7bfac8d5a6026d5d6f3a495be0391506.tar.gz
gcc-1595a1cb7bfac8d5a6026d5d6f3a495be0391506.tar.bz2
match.pd: A ^ ((A ^ B) & -(C cmp D)) -> (C cmp D) ? B : A simplification [PR94786]
We already have x - ((x - y) & -(z < w)) and x + ((y - x) & -(z < w)) simplifications, this one adds x ^ ((x ^ y) & -(z < w)) (not merged using for because of the :c that can be present on bit_xor and can't on minus). 2020-05-08 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/94786 * match.pd (A ^ ((A ^ B) & -(C cmp D)) -> (C cmp D) ? B : A): New simplification. * gcc.dg/tree-ssa/pr94786.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/match.pd12
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr94786.c66
4 files changed, 85 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9a380a5..5373046 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
2020-05-08 Jakub Jelinek <jakub@redhat.com>
+ PR tree-optimization/94786
+ * match.pd (A ^ ((A ^ B) & -(C cmp D)) -> (C cmp D) ? B : A): New
+ simplification.
+
PR target/94857
* config/i386/i386.md (peephole2 after *add<mode>3_cc_overflow_1): New
define_peephole2.
diff --git a/gcc/match.pd b/gcc/match.pd
index e8c53e3..58a4ac6 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2800,6 +2800,18 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& (TYPE_PRECISION (TREE_TYPE (@4)) >= TYPE_PRECISION (type)
|| !TYPE_UNSIGNED (TREE_TYPE (@4)))
&& (GIMPLE || !TREE_SIDE_EFFECTS (@1)))
+ (cond (cmp @2 @3) @1 @0)))
+ /* Similarly with ^ instead of - though in that case with :c. */
+ (simplify
+ (bit_xor:c @0 (bit_and:c (bit_xor:c @0 @1)
+ (convert? (negate@4 (convert? (cmp@5 @2 @3))))))
+ (if (INTEGRAL_TYPE_P (type)
+ && INTEGRAL_TYPE_P (TREE_TYPE (@4))
+ && TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE
+ && INTEGRAL_TYPE_P (TREE_TYPE (@5))
+ && (TYPE_PRECISION (TREE_TYPE (@4)) >= TYPE_PRECISION (type)
+ || !TYPE_UNSIGNED (TREE_TYPE (@4)))
+ && (GIMPLE || !TREE_SIDE_EFFECTS (@1)))
(cond (cmp @2 @3) @1 @0))))
/* Simplifications of shift and rotates. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index db0a837..b95696f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2020-05-08 Jakub Jelinek <jakub@redhat.com>
+ PR tree-optimization/94786
+ * gcc.dg/tree-ssa/pr94786.c: New test.
+
PR target/94857
* gcc.target/i386/pr94857.c: New test.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94786.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94786.c
new file mode 100644
index 0000000..beb88da
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94786.c
@@ -0,0 +1,66 @@
+/* PR tree-optimization/94786 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR <" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR <" 4 "optimized" } } */
+
+static inline unsigned
+umax1 (unsigned a, unsigned b)
+{
+ return a ^ ((a ^ b) & -(a < b));
+}
+
+static inline unsigned
+umin1 (unsigned a, unsigned b)
+{
+ return a ^ ((a ^ b) & -(a > b));
+}
+
+static inline int
+smax1 (int a, int b)
+{
+ return a ^ ((a ^ b) & -(a < b));
+}
+
+static inline int
+smin1 (int a, int b)
+{
+ return a ^ ((a ^ b) & -(a > b));
+}
+
+static inline unsigned long long
+umax2 (unsigned long long a, unsigned long long b)
+{
+ return a ^ ((a ^ b) & -(a <= b));
+}
+
+static inline unsigned long long
+umin2 (unsigned long long a, unsigned long long b)
+{
+ return a ^ ((a ^ b) & -(a >= b));
+}
+
+static inline long long
+smax2 (long long a, long long b)
+{
+ return a ^ ((a ^ b) & -(a <= b));
+}
+
+static inline long long
+smin2 (long long a, long long b)
+{
+ return a ^ ((a ^ b) & -(a >= b));
+}
+
+void
+test (unsigned *x, int *y, unsigned long long *z, long long *w)
+{
+ x[2] = umax1 (x[0], x[1]);
+ x[5] = umin1 (x[2], x[3]);
+ y[2] = smax1 (y[0], y[1]);
+ y[5] = smin1 (y[2], y[3]);
+ z[2] = umax2 (z[0], z[1]);
+ z[5] = umin2 (z[2], z[3]);
+ w[2] = smax2 (w[0], w[1]);
+ w[5] = smin2 (w[2], w[3]);
+}