[PATCH] math: Add optimization barrier to ensure a1 + u.d is not reused [BZ #30664]
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Wed Feb 26 19:35:45 GMT 2025
On 25/02/25 17:47, Dave Anglin wrote:
> On 2025-02-25 2:27 p.m., Adhemerval Zanella Netto wrote:
>> On 07/02/25 14:00, John David Anglin wrote:
>>> This patch fixes the test fma fails seen on hppa with gcc-13 and
>>> later.
>>>
>>> There may be more instances of this problem still lurking in
>>> sysdeps/ieee754/dbl-64/s_fma.c and other similar files. Whether
>>> they occur in practice is very hardware dependent. I'm not able
>>> to test changes to any other files on hppa.
>>>
>>> Okay?
>>>
>>> Dave
>>> ---
>>>
>>> math: Add optimization barrier to ensure a1 + u.d is not reused [BZ #30664]
>>>
>>> A number of fma tests started to fail on hppa when gcc was changed to
>>> use Ranger rather than EVRP. Eventually I found that the value of
>>> a1 + u.d in this is block of code was being computed in FE_TOWARDZERO
>>> mode and not the original rounding mode:
>>>
>>> if (TININESS_AFTER_ROUNDING)
>>> {
>>> w.d = a1 + u.d;
>>> if (w.ieee.exponent == 109)
>>> return w.d * 0x1p-108;
>>> }
>>>
>>> This caused the exponent value to be wrong and the wrong return path
>>> to be used.
>> Is there some compiler annotation/attribute to mark libc_fesetround and
>> any other function as compiler barrier to avoid such issue?
>
> I'm not aware of a simple way to do this. The problem is the values of non
> call-clobbered registers are preserved across calls.
>
> "asm volatile ("" : : : "memory");" is a compiler scheduling barrier for all
> expressions that load from or store to memory. For this to work, floating
> point values would have to be forced to memory to complete their evaluation.
> This is effectively what math_opt_barrier does but for a single argument.
>
> It evaluates and returns its floating-point argument. This ensures that the
> evaluation of any expression using the result of math_opt_barrier is not moved
> before the barrier. This is probably the best solution from an optimization
> standpoint but it is tricky to know which values need barriers.
It seems that glibc is not the first project to be bitten with such
issue [1], and while the C standard does have a way to prevent this
(FENV_ACCESS), it is not implemented by gcc and the bug report work
around is indeed to add math barriers.
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34678
>
>> Another possibility would to rewrite it to avoid FP operations.
>
> This probably would significantly degrade performance. It would be straight
> forward to implement if soft add and multiply routines were available with
> rounding support.
Last time I checked a integer based implementation (musl), it was faster
than glibc one even on recent hardware. But I don't think this is pressing
issue since now most hardware does have fma instructions.
More information about the Libc-alpha
mailing list