[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