summaryrefslogtreecommitdiff
path: root/gcc/match.pd
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-05-05 11:31:43 +0200
committerJakub Jelinek <jakub@redhat.com>2020-05-05 11:34:45 +0200
commit6d938a5d770d0e94ecd923d20006b05126659235 (patch)
tree3f679604b715d12a623eb19e7df56d4171024b2d /gcc/match.pd
parent59e4474a22cbf23b777f244d2a28d1ee4b54d3ce (diff)
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/match.pd')
-rw-r--r--gcc/match.pd21
1 files changed, 21 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 9c1e23984d6..c45e94c0c6a 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