On 8/4/2026 7:51 AM, [email protected] wrote:
From: Kyrylo Tkachov <[email protected]>

v2: Add flag_associative_math on top of flag_reciprocal_math as
condition

(A / B) * (C / D) is (A * C) / (B * D), which replaces one of the two
divisions with a multiply.  The operation count is unchanged and a division
costs several multiplies on every target.

   double f (double a, double b, double c)
   { return (a / b) * (1.0 / c); }

aarch64 -Ofast before:

        fdiv    d0, d0, d1
        fdiv    d0, d0, d2

after:

        fmul    d1, d1, d2
        fdiv    d0, d0, d1

The reciprocal spelling is what appears in source that has been hand-tuned
for -freciprocal-math: the reciprocal is folded into a quotient by the
existing rules, but the resulting division of a division was never revisited
because the multiply had already consumed it.  The existing (A/B)/C rule
therefore only caught the case where the second division was written out.

The rule also needs infinities and NaNs excluded.  It forms two products,
and each is a new place for the exponent to leave the range: with both
divisors large B * D is an infinity and the quotient becomes inf / inf, with
both small it is a zero and the quotient becomes 0 / 0, and either turns a
finite result into a NaN.  The cancellation rules in the same block carry
the same test for the same reason.

Complex values also require signed zeros to be ignored,
because reassociation can change the sign of an imaginary zero.

Bootstrapped and tested on aarch64-none-linux-gnu.
Ok for trunk?
Thanks,
Kyrill

gcc/ChangeLog:

        * match.pd ((A / B) * (C / D)): New simplification.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/recip-mult-div-1.c: New test.
        * gcc.dg/tree-ssa/recip-mult-div-2.c: New test.

Signed-off-by: Kyrylo Tkachov <[email protected]>
I don't guess you've done something like test spec2017 or spec2026 with this?  One of the guidelines we've had for the -ffast-math family is they don't break specfp.  So it would be best to verify spec is still OK with -ffast-math (or the narrower set to allow reassociation and turn off -0.0 support)

Assuming that test is OK, then this is fine for the trunk.   Sorry to add the additional testing request, but I've been bitten by these kinds of things too many times.

Jeff

Reply via email to