diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-05-05 11:31:43 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-05-05 11:34:45 +0200 |
commit | 6d938a5d770d0e94ecd923d20006b05126659235 (patch) | |
tree | 3f679604b715d12a623eb19e7df56d4171024b2d /gcc | |
parent | 59e4474a22cbf23b777f244d2a28d1ee4b54d3ce (diff) | |
download | gcc-6d938a5d770d0e94ecd923d20006b05126659235.zip gcc-6d938a5d770d0e94ecd923d20006b05126659235.tar.gz gcc-6d938a5d770d0e94ecd923d20006b05126659235.tar.bz2 |
match.pd: Optimize (((type)A * B) >> prec) != 0 into __imag__ .MUL_OVERFLOW [PR94914]
On x86 (the only target with umulv4_optab) one can use mull; seto to check
for overflow instead of performing wider multiplication and performing
comparison on the high bits.
2020-05-05 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/94914
* match.pd ((((type)A * B) >> prec) != 0 to .MUL_OVERFLOW(A, B) != 0):
New simplification.
* gcc.target/i386/pr94914.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/match.pd | 21 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr94914.c | 17 |
4 files changed, 49 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8c46dcd..e51c0e0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-05-05 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/94914 + * match.pd ((((type)A * B) >> prec) != 0 to .MUL_OVERFLOW(A, B) != 0): + New simplification. + 2020-05-05 Uroš Bizjak <ubizjak@gmail.com> * config/i386/i386.md (*testqi_ext_3): Use diff --git a/gcc/match.pd b/gcc/match.pd index 9c1e239..c45e94c 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4776,6 +4776,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (with { tree t = TREE_TYPE (@0), cpx = build_complex_type (t); } (out (imagpart (IFN_MUL_OVERFLOW:cpx @0 @1)) { build_zero_cst (t); }))))) +/* Similarly, for unsigned operands, (((type) A * B) >> prec) != 0 where type + is at least twice as wide as type of A and B, simplify to + __builtin_mul_overflow (A, B, <unused>). */ +(for cmp (eq ne) + (simplify + (cmp (rshift (mult:s (convert@3 @0) (convert @1)) INTEGER_CST@2) + integer_zerop) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && INTEGRAL_TYPE_P (TREE_TYPE (@3)) + && TYPE_UNSIGNED (TREE_TYPE (@0)) + && (TYPE_PRECISION (TREE_TYPE (@3)) + >= 2 * TYPE_PRECISION (TREE_TYPE (@0))) + && tree_fits_uhwi_p (@2) + && tree_to_uhwi (@2) == TYPE_PRECISION (TREE_TYPE (@0)) + && types_match (@0, @1) + && type_has_mode_precision_p (TREE_TYPE (@0)) + && (optab_handler (umulv4_optab, TYPE_MODE (TREE_TYPE (@0))) + != CODE_FOR_nothing)) + (with { tree t = TREE_TYPE (@0), cpx = build_complex_type (t); } + (cmp (imagpart (IFN_MUL_OVERFLOW:cpx @0 @1)) { build_zero_cst (t); }))))) + /* Simplification of math builtins. These rules must all be optimizations as well as IL simplifications. If there is a possibility that the new form could be a pessimization, the rule should go in the canonicalization diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 09f8995..2a44c70 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-05-05 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/94914 + * gcc.target/i386/pr94914.c: New test. + 2020-05-04 Patrick Palka <ppalka@redhat.com> PR c++/94038 diff --git a/gcc/testsuite/gcc.target/i386/pr94914.c b/gcc/testsuite/gcc.target/i386/pr94914.c new file mode 100644 index 0000000..932bd21 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr94914.c @@ -0,0 +1,17 @@ +/* PR tree-optimization/94914 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler "\tseto\t" } } */ +/* { dg-final { scan-assembler "\tsetno\t" } } */ + +int +foo (unsigned int x, unsigned int y) +{ + return (((unsigned long long)x * y) >> 32) != 0; +} + +int +bar (unsigned int x, unsigned int y) +{ + return (((unsigned long long)x * y) >> 32) == 0; +} |