Hi all,
I would like to propose allowing floating-point atomicrmw instructions to carry fast-math flags.
A prototype implementation is available in PR #211267.
Overview
The proposed syntax allows existing fast-math flags to appear on an atomicrmw:
%old = atomicrmw nnan fadd ptr %ptr, float %value monotonic
%old = atomicrmw fast fadd ptr %ptr, double %value seq_cst
The flags would have the same meaning as documented for other instructions in the LLVM LangRef, with one atomicrmw-specific clarification:
Fast-math flags additionally apply to the value written to memory.
This clarification is necessary because the current definitions of nnan and ninf apply only to input operands and the result, which does not provide a sufficiently strong constraint for atomicrmw node.
Motivation
The motivating case is the AArch64 FEAT_LSFE extension, which provides native atomic floating-point memory instructions such as LDFADD. Without using these instructions, an atomicrmw fadd is lowered to a compare-and-swap loop that calculates the new value using an ordinary FADD floating-point instruction.
Unlike the FADD instruction present in the loop, whose behaviour is determined by FPCR register, the LDFADD has fixed floating-point behaviour which can differ from the FADD one. In particular, it behaves as if default-NaN mode is enabled. We therefore want an explicit IR-level indication that NaN behaviour is not relevant before selecting LDFADD. The nnan flag provides this information and would allow the AArch64 backend to lower the operation directly to LDFADD.
Note: The current LangRef already permits an unflagged floating-point operation to produce the preferred NaN. However, relying on this would mean that the observable result of the same IR could change when compiling for a newer architecture that supports LDFADD.
Although such a transformation may technically be permitted by the current semantics, this behaviour is counter-intuitive. Users would reasonably expect enabling a new architectural feature to improve code generation without changing floating-point results. Requiring nnan makes this change explicit and ensures that LDFADD is selected only when the IR states that NaN behaviour is irrelevant.
Applicability
The proposal applies only to atomicrmw operations that perform floating-point arithmetic.
Fast-math flags would therefore be accepted for operations such as:
fadd
fsub
fmax
fmin
fmaximum
fminimum
fmaximumnum
fminimumnum
Questions
- Should
atomicrmwaccept the complete set of fast-math flags, as proposed, or only a subset such asnnan,ninfandnsz? - Is it reasonable for the AArch64 backend to require
nnanbefore selecting an LSFE instruction, even if the current LangRef could technically permit the instruction’s default-NaN behaviour for unflagged IR? - More generally, should LLVM allow the result of an atomic floating-point operation to change solely because a newer target feature enables a different lowering, as the current LangRef appears to permit, or should such a change require an explicit fast-math assumption in the IR?
Feedback on the proposed semantics would be appreciated.