On 5/10/25 9:46 PM, Vineet Gupta wrote:


Frankly I'm surprised we need FRM adjustments as much as we do, though
presumably there's some builtin or somesuch that we need to twiddle FRM
to implement and as a result if the builtin ever gets used it leads to
FRM games.  But it still seems high.


The mode switching state machine executes even when there are just function
calls and returns and as we saw if there are bugs there, it just misfires.
e.g. The frm restore in 5/6 was kicking in even when static RM was never seen in
the function. Combined with our early preemptive save, we can get into a state
where both save/restore end up getting generated.

We ideally need a pre-scan of cfun for any RM changes, frm updates etc and if
none just exit early.
I don't know if that is what we would consider.
Possibly. Usually this kind of prescan would be an attempt to improve compile-times. I wouldn't use it to work around implementation issues generating too many FRM adjustments.





For example, what does xz do that
triggers any FRM adjustments, even statically?!?

         __letf2    1    0    0
__printf_fp_buffer_1.isra.0    1    0    0
__printf_fphex_buffer    3    0    0
      __unordtf2    1    0    0

Those are glibc routines for math emulation routines which are written using
templatized macros.
One of those FP_INIT_ROUNDMODE uses inline asm to do a FRM read - we need a
builtin for compiler to optimize away some of those reads.

# define FP_INIT_ROUNDMODE            \
do {                        \
   __asm__ volatile ("frrm %0" : "=r" (_frm));    \
} while (0)


Ugh. If we look at glibc I don't immediately see where we'd be getting uses of FP_INIT_ROUNDMODE except via sqrt or 128-bit FP emulation. I guess we could have 128-bit FP support inside some of the *printf code, which could trigger pulling in letf2 and friends through various non-obvious ways.

So let's set this question aside. That's enough to satisfy my curiosity about the potential oddball ways we can get FRM adjustments.

Jeff

Reply via email to