On Wed, 11 Mar 2026, Matthew Malcomson wrote:

> Ping on these design questions.
> 
> Reminder of where I believe we are:
> - It seems that in order to effectively use the AArch64 floating point atomic
> instructions there needs to be a builtin defined with the FP environment
> semantics of the C++26 fetch_add/fetch_sub methods.  I.e. "The floating-point
> environment ([cfenv]) for atomic arithmetic operations on floating-​point-type
> may be different than the calling thread's floating-point environment."
> (N.b. in both behaviour on NaN and FP exceptions).
> 
> I would like to make the generic `__atomic_fetch_add` have this behaviour.
> 
> On IRC Joseph mentioned that he's not sure on the decision either way -- maybe
> there could be new library functions in the future that would want to handle
> FP environment similar to the existing C _Atomic behaviour.
> 
> Jonathan mentioned he's in favour of this (from a libstdc++ perspective,
> because this maps most closely with what libstdc++ needs).
> 
> It doesn't feel like we have a consensus agreeing or disagreeing with the
> suggestion above.  Which I would take to imply that patches implementing the
> above would not be accepted.
> 
> Is there any information that I could find that could help us find a consensus
> one way or the other?

May I suggest you do arm specific builtins which you should be able to
wire into libstdc++.  As for C __atomic_fetch_add there should at least
be a proposal to the C standards committee with regard to such feature.

You cannot be targeting existing code which means you are essentially
proposing language extensions here.

Richard.

> Cheers,
> Matthew
> 
> On 3/5/26 09:03, Matthew Malcomson wrote:
> > Ping on these design questions.
> > 
> > On 2/27/26 11:20, Matthew Malcomson wrote:
> >> External email: Use caution opening links or attachments
> >>
> >>
> >> Hello,
> >>
> >> First I'd like to ping for others opinion on the my previous design
> >> questions around floating point atomic operations.
> >> - Any contrary opinions on the builtin semantics matching the libstdc++
> >>    fetch_add semantics?
> >> - Do people agree on my conclusion that pattern-matching an FP CAS loop
> >>    to use a builtin with these relaxed FP semantics is awkward enough to
> >>    not be worthwhile?
> >>
> >> ------------------------------
> >> Second: while working on expanding these floating point atomic
> >> operations in the mid-end (after IPA) I've hit a few tricky points.
> >>
> >> If we are defining the floating point exception semantics of these
> >> builtins to be the same as the libstdc++ floating point fetch_add
> >> methods (i.e. can be executed in a different floating point environment
> >> as the calling thread), then we still have the question of whether the
> >> builtin can *pollute* the calling threads floating point environment.
> >>
> >> As it stands the CAS implementation in libstdc++ could go around the
> >> compare exchange loop multiple times and set floating point
> >> status/exception flags according to one of the operations that didn't
> >> end up getting stored in memory.
> >> While the C++ specification of this operation allows the operation to be
> >> performed in a "different" floating point environment to the calling
> >> thread, I would not read that as allowing such pollution of the
> >> environment.
> >>
> >> Since I'm hoping these builtins become the standard approach to
> >> performing the floating point fetch_add/sub operations, I expect that it
> >> would be best if they do not do such "polluting" of the calling threads
> >> environment.
> >>
> >> For the AArch64 instruction recently defined this is not a problem (the
> >> instruction doesn't set any flags).  However when expanding to a CAS
> >> loop in the mid-end when no optab is defined I believe I have to add
> >> some floating point exception handling code.
> >>
> >> Questions:
> >> 1) Am I missing anything?  Is there some reason that this is not
> >>     necessary?
> >> 2) Since the builtin will be defined to not necessarily set floating
> >>     point exceptions or status flags, I would guess that something
> >>     implementing `feholdexcept(&fenv); <CAS loop>; fesetenv(&fenv)`
> >>     would be better than the full handling as is done for the C `_Atomic`
> >>     feature.  Do others agree?
> >> 3) W.r.t. implementation -- it seems there would be two feasible
> >>     approaches:
> >>     - Add new sync-builtins along the lines of `__atomic_feraiseexcept`
> >>       so that the mid-end can emit calls to these directly.
> >>     - Add a new target hook similar to `atomic_assign_expand_fenv` but
> >>       that returns GIMPLE and provides `fesetenv` instead of
> >>       `feupdateenv` and `feclearexcept`.
> >>     I'm guessing that the second option (new target hook) would be the
> >>     best since it means we can inline the operations.
> >>     Do others agree?
> >>
> >> Thanks,
> >> Matthew
> >>
> >>
> >> On 2/23/26 17:05, Jonathan Wakely wrote:
> >>> External email: Use caution opening links or attachments
> >>>
> >>>
> >>> On Mon, 23 Feb 2026 at 12:01, Matthew Malcomson <[email protected]>
> >>> wrote:
> >>>>
> >>>> Hello all,
> >>>>
> >>>> I'm focussing back on the atomic floating point fetch add/fetch sub
> >>>> operations.
> >>>>
> >>>> Andre and Wilco brought some things around floating point exceptions to
> >>>> my attention that I'd missed at the time.
> >>>>
> >>>> First, it seems the relevant AArch64 instructions do not raise floating
> >>>> point exceptions and do not set floating point status flags.
> >>>> https://developer.arm.com/documentation/ddi0602/2025-12/SIMD-FP-
> >>>> Instructions/LDFADD--LDFADDA--LDFADDAL--LDFADDL--Atomic-floating-
> >>>> point-add-?lang=en
> >>>> .
> >>>> AIUI this also holds for the existing floating point atomic operations
> >>>> that are available on GPU's.
> >>>>
> >>>> On looking back at the new C++ atomic<float>::fetch_add methods with
> >>>> this in mind, it seems they have explicitly relaxed semantics around
> >>>> floating point exceptions (https://eel.is/c++draft/ atomics#ref.float-8).
> >>>>    The quote there is "The floating-point environment ([cfenv]) for
> >>>> atomic arithmetic operations on floating-point-type may be different
> >>>> than the calling thread's floating-point environment".
> >>>>
> >>>> Given this new information I believe the new atomic intrinsics should
> >>>> have the semantics of the new libstdc++ methods -- i.e. allowing the
> >>>> floating point environment of the operation to be different to that of
> >>>> the calling thread.
> >>>> The main reason for this being that we are interested in adding this new
> >>>> intrinsic in order to ensure compilers can emit the most performant
> >>>> instructions for code using this new libstdc++ method, and C `_Atomic`
> >>>> is a language feature that does not need to be tied to the behaviour of
> >>>> a builtin.
> >>>>
> >>>> Does this seem reasonable to everyone?
> >>>
> >>> I am selfishly in favour of the builtins matching the semantics that
> >>> libstdc++ wants :-)
> >>>
> >>> But yes, I agree that if the standard allows the atomic ops to ignore
> >>> the current FP env, and some targets can emit more efficient code by
> >>> taking advantage of that permission, then it makes sense to do that.
> >>>
> >>>>
> >>>>
> >>>> One less-obvious consequence of this is around pattern matching a CAS
> >>>> loop (which I originally planned to do in order to match the approach
> >>>> taken for fetch_min/fetch_max).  It seems that this would require a
> >>>> "replay" operation to be added around the atomic internal function in
> >>>> order to provide the same floating point exception semantics as the
> >>>> original loop.
> >>>>
> >>>> An extra question about AArch64 floating point semantics for Andre and
> >>>> Wilco:  The instruction mentions it behaves as if `FPCR.AH is 0` and
> >>>> `FPCR.DN is 1`:  Is this the case for standard code?
> >>>> If not I guess that would mean that pattern matching a C-level CAS loop
> >>>> to use the new atomic operations would leave incorrect values in memory?
> >>>>
> >>>> Both of these points make me wonder whether pattern-matching an existing
> >>>> CAS loop to these new instructions is worthwhile/feasible
> >>>> (respectively).  What are peoples thoughts on that?
> >>>>
> >>>> MM
> >>>>
> >>>> On 9/19/24 22:38, Joseph Myers wrote:
> >>>>> External email: Use caution opening links or attachments
> >>>>>
> >>>>>
> >>>>> On Thu, 19 Sep 2024, [email protected] wrote:
> >>>>>
> >>>>>> 6) Anything special about floating point maths that I'm tripping up on?
> >>>>>
> >>>>> Correct atomic operations with floating-point operands should ensure
> >>>>> that
> >>>>> exceptions raised exactly correspond to the operands for which the
> >>>>> operation succeeded, and not to the operands for any previous attempts
> >>>>> where the compare-exchange failed.  There is a lengthy note in the C
> >>>>> standard (in C11 it's a footnote in 6.5.16.2, in C17 it's a Note in
> >>>>> 6.5.16.2 and in C23 that subclause has become 6.5.17.3) that discusses
> >>>>> appropriate code sequences to achieve this.  In GCC the implementation
> >>>>> of
> >>>>> this is in c-typeck.cc:build_atomic_assign, which in turn calls
> >>>>> targetm.atomic_assign_expand_fenv (note that we have the complication
> >>>>> for
> >>>>> C of not introducing libm dependencies in code that only uses standard
> >>>>> language features and not <math.h>, <fenv.h> or <complex.h>, so direct
> >>>>> use
> >>>>> of <fenv.h> functions is inappropriate here).
> >>>>>
> >>>>> I would expect such built-in functions to follow the same semantics for
> >>>>> floating-point exceptions as _Atomic compound assignment does. (Note
> >>>>> that
> >>>>> _Atomic compound assignment is more general in the allowed operands,
> >>>>> because compound assignment is a heterogeneous operation - for example,
> >>>>> the special floating-point logic in build_atomic_assign includes the
> >>>>> case
> >>>>> where the LHS of the compound assignment is of atomic integer type but
> >>>>> the
> >>>>> RHS is of floating type.  However, built-in functions allow memory
> >>>>> orders
> >>>>> other than seq_cst to be used, whereas _Atomic compound assignment is
> >>>>> limited to the seq_cst case.)
> >>>>>
> >>>>> So it would seem appropriate for the implementation of such built-in
> >>>>> functions to make use of targetm.atomic_assign_expand_fenv for
> >>>>> floating-point environment handling, and for testcases to include tests
> >>>>> analogous to c11-atomic-exec-5.c that exceptions are being handled
> >>>>> correctly.
> >>>>>
> >>>>> Cf. N2329 which suggested such operations for C in <stdatomic.h> (but
> >>>>> tried to do to many things in one paper to be accepted into C); it
> >>>>> didn't
> >>>>> go into the floating-point exceptions semantics but simple correctness
> >>>>> would indicate avoiding spurious exceptions from discarded computations.
> >>>>>
> >>>>> -- 
> >>>>> Joseph S. Myers
> >>>>> [email protected]
> >>>>>
> >>>>
> >>>
> >>
> > 
> 
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to