Subject: Re: bug#42147: 28.0.50; pure vs side-effect-free, missing optimizations?

From: Paul Eggert <[email-masked]>
Date: Thu, 2 Jul 2020 16:16:04 -0700

On 7/2/20 2:41 PM, Stefan Monnier wrote:
> I'd tend to assume that x87 rounding can virtually never be seen from
> Elisp because it's hard to imagine how the C compiler will manage to
> keep our Elisp floats long enough in the x87 stack to avoid rounding
> back to 64bit floats between every Elisp-level operation.

It can happen in floatop_arith_driver, which has an accumulator of type 'double'
that on x87 is put into an 80-bit register. For example, on x86+x87 compiled
with the usual gcc -O2, (+ 1e16 2.9999 2.9999) returns 10000000000000008.0 (the
exact answer rounded to 'double'), whereas with SSE2 the same expression yields
10000000000000004.0 (which is a bit off, because the accumulator is only 64 bits
and suffered from rounding intermediate results).

> Or are we worried about the double-rounding of x87?

That too. For example, with x87, (+ 1e16 2.9999) yields 10000000000000004.0 due
to double-rounding, whereas with SSE2 the same expression yields
10000000000000002.0 which is the correctly-rounded answer.

As you can see, sometimes SSE2 is closer to the mathematically-correct answer
and sometimes x87 is. In typical C math code, x87 is better; in Emacs I imagine
the reverse is true (for the reasons you mentioned), though I have not attempted
to measure this.