This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: [RFH] Move some flag_unsafe_math_optimizations using simplify and match
- From: Marc Glisse <marc dot glisse at inria dot fr>
- To: "Hurugalawadi, Naveen" <Naveen dot Hurugalawadi at caviumnetworks dot com>
- Cc: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>, Richard Biener <richard dot guenther at gmail dot com>
- Date: Tue, 11 Aug 2015 10:07:27 +0200 (CEST)
- Subject: Re: [RFH] Move some flag_unsafe_math_optimizations using simplify and match
- Authentication-results: sourceware.org; auth=none
- References: <SN2PR0701MB1024EFC093CC2E3BCB62F0388E730 at SN2PR0701MB1024 dot namprd07 dot prod dot outlook dot com>
- Reply-to: gcc at gcc dot gnu dot org
On Fri, 7 Aug 2015, Hurugalawadi, Naveen wrote:
Please find attached the patch "simplify-1.patch" that moves some
"flag_unsafe_math_optimizations" from fold-const.c to simplify and match.
Some random comments (not a review).
First, patches go to gcc-patches@gcc.gnu.org.
/* fold_builtin_logarithm */
(if (flag_unsafe_math_optimizations)
Please indent everything below by one space.
+
+/* Simplify sqrt(x) * sqrt(x) -> x. */
+(simplify
+ (mult:c (SQRT @0) (SQRT @0))
(mult (SQRT@1 @0) @1)
+ (if (!HONOR_SNANS (element_mode (type)))
You don't need element_mode here, HONOR_SNANS (type) should do the right
thing.
+ @0))
+
+/* Simplify root(x) * root(y) -> root(x*y). */
+/* FIXME : cbrt ICE's with AArch64. */
+(for root (SQRT CBRT)
Indent below.
+(simplify
+ (mult:c (root @0) (root @1))
No need to commute, it yields the same pattern. On the other hand, you
may want root:s since if the roots are going to be computed anyway, a
multiplication is cheaper than computing yet another root (I didn't
check what the existing code does).
(this applies to several other patterns)
+ (root (mult @0 @1))))
+
+/* Simplify expN(x) * expN(y) -> expN(x+y). */
+(for exps (EXP EXP2)
+/* FIXME : exp2 ICE's with AArch64. */
+(simplify
+ (mult:c (exps @0) (exps @1))
+ (exps (plus @0 @1))))
I am wondering if we should handle mixed operations (say
expf(x)*exp2(y)), for this pattern and others, but that's not a
prerequisite.
+
+/* Simplify pow(x,y) * pow(x,z) -> pow(x,y+z). */
+(simplify
+ (mult:c (POW @0 @1) (POW @0 @2))
+ (POW @0 (plus @1 @2)))
+
+/* Simplify pow(x,y) * pow(z,y) -> pow(x*z,y). */
+(simplify
+ (mult:c (POW @0 @1) (POW @2 @1))
+ (POW (mult @0 @2) @1))
+
+/* Simplify tan(x) * cos(x) -> sin(x). */
+(simplify
+ (mult:c (TAN @0) (COS @0))
+ (SIN @0))
Since this will only trigger for the same version of cos and tan (say cosl
with tanl or cosf with tanf), I am wondering if we get smaller code with a
linear 'for' or with a quadratic 'for' which shares the same tail (I
assume the above is quadratic, I did not check). This may depend on
Richard's latest patches.
+
+/* Simplify x * pow(x,c) -> pow(x,c+1). */
+(simplify
+ (mult:c @0 (POW @0 @1))
+ (if (TREE_CODE (@1) == REAL_CST
+ && !TREE_OVERFLOW (@1))
+ (POW @0 (plus @1 { build_one_cst (type); }))))
+
+/* Simplify sin(x) / cos(x) -> tan(x). */
+(simplify
+ (rdiv (SIN @0) (COS @0))
+ (TAN @0))
+
+/* Simplify cos(x) / sin(x) -> 1 / tan(x). */
+(simplify
+ (rdiv (COS @0) (SIN @0))
+ (rdiv { build_one_cst (type); } (TAN @0)))
+
+/* Simplify sin(x) / tan(x) -> cos(x). */
+(simplify
+ (rdiv (SIN @0) (TAN @0))
+ (if (! HONOR_NANS (@0)
+ && ! HONOR_INFINITIES (element_mode (@0)))
+ (cos @0)))
+
+/* Simplify tan(x) / sin(x) -> 1.0 / cos(x). */
+(simplify
+ (rdiv (TAN @0) (SIN @0))
+ (if (! HONOR_NANS (@0)
+ && ! HONOR_INFINITIES (element_mode (@0)))
+ (rdiv { build_one_cst (type); } (COS @0))))
+
+/* Simplify pow(x,c) / x -> pow(x,c-1). */
+(simplify
+ (rdiv (POW @0 @1) @0)
+ (if (TREE_CODE (@1) == REAL_CST
+ && !TREE_OVERFLOW (@1))
+ (POW @0 (minus @1 { build_one_cst (type); }))))
+
+/* Simplify a/root(b/c) into a*root(c/b). */
+/* FIXME : cbrt ICE's with AArch64. */
+(for root (SQRT CBRT)
+(simplify
+ (rdiv @0 (root (rdiv @1 @2)))
+ (mult @0 (root (rdiv @2 @1)))))
+
+/* Simplify x / expN(y) into x*expN(-y). */
+/* FIXME : exp2 ICE's with AArch64. */
+(for exps (EXP EXP2)
+(simplify
+ (rdiv @0 (exps @1))
+ (mult @0 (exps (negate @1)))))
+
+/* Simplify x / pow (y,z) -> x * pow(y,-z). */
+(simplify
+ (rdiv @0 (POW @1 @2))
+ (mult @0 (POW @1 (negate @2))))
+
/* Special case, optimize logN(expN(x)) = x. */
(for logs (LOG LOG2 LOG10)
exps (EXP EXP2 EXP10)
--
Marc Glisse