[clang] Add clang atomic control options and attribute (PR #114841)
Hubert Tong via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 24 09:50:57 PST 2025
================
@@ -5442,6 +5442,155 @@ third argument, can only occur at file scope.
a = b[i] * c[i] + e;
}
+Extensions for controlling atomic code generation
+=================================================
+
+The ``[[clang::atomic]]`` statement attribute enables users to control how
+atomic operations are lowered in LLVM IR by conveying additional metadata to
+the backend. The primary goal is to allow users to specify certain options,
+like whether atomic operations may be performed on specific types of memory or
+whether to ignore denormal mode correctness in floating-point operations,
+without affecting the correctness of code that does not rely on these behaviors.
+
+In LLVM, lowering of atomic operations (e.g., ``atomicrmw``) can differ based
+on the target's capabilities. Some backends support native atomic instructions
+only for certain operation types or alignments, or only in specific memory
+regions. Likewise, floating-point atomic instructions may or may not respect
+IEEE denormal requirements. When the user is unconcerned about denormal-mode
+compliance (for performance reasons) or knows that certain atomic operations
+will not be performed on a particular type of memory, extra hints are needed to
+tell the backend how to proceed.
+
+A classic example is an architecture where floating-point atomic add does not
+fully conform to IEEE denormal-mode handling. If the user does not mind ignoring
+that aspect, they would prefer to still emit a faster hardware atomic instruction,
+rather than a fallback or CAS loop. Conversely, on certain GPUs (e.g., AMDGPU),
+memory accessed via PCIe may only support a subset of atomic operations. To ensure
+correct and efficient lowering, the compiler must know whether the user wants to
+allow atomic operations on that type of memory.
+
+The allowed atomic attribute values are now ``remote_memory``, ``fine_grained_memory``,
+and ``ignore_denormal_mode``, each optionally prefixed with ``no_``. The meanings
+are as follows:
+
+- ``remote_memory`` means atomic operations may be performed on remote memory.
+ Prefixing with ``no_`` (i.e. ``no_remote_memory``) indicates that atomic
+ operations should not be performed on remote memory.
+- ``fine_grained_memory`` means atomic operations may be performed on fine-grained
+ memory. Prefixing with ``no_`` (i.e. ``no_fine_grained_memory``) indicates that
+ atomic operations should not be performed on fine-grained memory.
+- ``ignore_denormal_mode`` means that atomic operations are allowed to ignore
+ correctness for denormal mode in floating-point operations, potentially improving
+ performance on architectures that handle denormals inefficiently. The negated form,
+ if specified as ``no_ignore_denormal_mode``, would enforce strict denormal mode
+ correctness.
+
+Within the same atomic attribute, duplicate and conflict values are accepted and the
+last value of conflicting values wins. Multiple atomic attributes are allowed
+for the same compound statement and the last atomic attribute wins.
+
+Without any atomic metadata, LLVM IR defaults to conservative settings for
+correctness: atomic operations are assumed to use remote memory, fine-grained
+memory, and enforce denormal mode correctness (i.e. the equivalent of
+``remote_memory``, ``fine_grained_memory``, and ``no_ignore_denormal_mode``).
+
+The attribute may be applied only to a compound statement and looks like:
+
+.. code-block:: c++
+
+ [[clang::atomic(remote_memory, fine_grained_memory, ignore_denormal_mode)]]
+ {
+ // Atomic instructions in this block carry extra metadata reflecting
+ // these user-specified options.
+ }
+
+You can provide one or more of these options, each optionally prefixed with
+``no_`` to negate that option. Any unspecified option is inherited from the
+global defaults, which can be set by a compiler flag or the target's built-in defaults.
+
+A new compiler option now globally sets the defaults for these atomic-lowering
+options. The command-line format has changed to:
+
+.. code-block:: console
+
+ $ clang -fatomic-remote-memory -fno-atomic-fine-grained-memory -fatomic-ignore-denormal-mode file.cpp
+
+Each option has a corresponding flag:
+``-fatomic-remote-memory`` / ``-fno-atomic-remote-memory``,
+``-fatomic-fine-grained-memory`` / ``-fno-atomic-fine-grained-memory``,
+and ``-fatomic-ignore-denormal-mode`` / ``-fno-atomic-ignore-denormal-mode``.
+
+Code using the ``[[clang::atomic]]`` attribute can then selectively override
+the command-line defaults on a per-block basis. For instance:
+
+.. code-block:: c++
+
+ // Suppose the global defaults assume:
+ // remote_memory, fine_grained_memory, and no_ignore_denormal_mode
+ // (for conservative correctness)
+
+ void example() {
+ // Locally override the settings: disable remote_memory and enable
+ // fine_grained_memory.
+ [[clang::atomic(no_remote_memory, fine_grained_memory)]]
+ {
+ // In this block:
+ // - Atomic operations are not performed on remote memory.
+ // - Atomic operations are performed on fine-grained memory.
+ // - The setting for denormal mode remains as the global default
+ // (typically no_ignore_denormal_mode, enforcing strict denormal mode correctness).
+ // ...
+ }
+ }
+
+Function bodies are not compound statements, so this will not work:
----------------
hubert-reinterpretcast wrote:
```suggestion
Function bodies do not accept statement attributes, so this will not work:
```
https://github.com/llvm/llvm-project/pull/114841
More information about the cfe-commits
mailing list