diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-05-08 10:52:47 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-05-08 10:52:47 +0200 |
commit | 1595a1cb7bfac8d5a6026d5d6f3a495be0391506 (patch) | |
tree | 701be1abe1fbf79e878cf47ce6728b11606b8483 /gcc | |
parent | a229f9b3737062c6e853879be6683f3f3e4a6661 (diff) | |
download | gcc-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/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/match.pd | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr94786.c | 66 |
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]); +} |