[Mlir-commits] [mlir] [mlir][llvmir] Add new support for strict fp handling (PR #205158)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Jun 25 11:49:54 PDT 2026


================
@@ -1790,4 +1790,183 @@ def LLVM_AnyMDAttr : AnyAttrOf<[
     LLVM_MDStringAttr, LLVM_MDConstantAttr, LLVM_MDFuncAttr, LLVM_MDNodeAttr],
     "LLVM metadata attribute (md_string, md_const, md_func, or md_node)">;
 
+//===----------------------------------------------------------------------===//
+// FenvAttr
+//===----------------------------------------------------------------------===//
+
+def LLVM_FenvAttr : LLVM_Attr<"Fenv", "fenv"> {
+  let summary = "Describes floating-point environment constraints";
+  let description = [{
+    The `#llvm.fenv` attribute describes constraints on the floating-point
+    handling of a floating-point operation. It can be attached to
+    floating-point operations to capture rounding and exception behavior. All
+    of its parameters are optional.
+
+    - `rounding_mode`: the rounding mode to use. Every value other than
+      `dynamic` specifies a static rounding mode.
+    - `dynamic_rounding_mode`: the known dynamic rounding mode at the point the
+      instruction is executed. Otherwise the behavior is undefined.
+    - `except_mode`: the known exception mode at the point the instruction is
+      executed. Otherwise the behavior is undefined.
+    - `strict_snan`: whether to handle sNaN according to IEEE rules (`true`) or
+      LLVM's relaxed NaN propagation rules (`false`). This flag is only
+      meaningful when `except_mode` is `unmasked` or `unknown`, where it
+      defaults to `true`; when `except_mode` is `masked` the flag is ignored.
+    - `strict_except`: if `false`, any case that would produce an FP exception
+      produces it non-deterministically instead (i.e. it may or may not occur).
+      This means the FP status is written non-deterministically, and, if
+      exceptions are unmasked, the instruction traps non-deterministically.
+      This flag is only meaningful when `except_mode` is `unmasked` or
+      `unknown`, where it defaults to `true`; when `except_mode` is `masked`
+      the flag is ignored.
+
+    When this attribute is present on an operation, the operation is lowered to
+    the corresponding `llvm.experimental.constrained.*` intrinsic during
+    translation to LLVM IR.
+
+    The default setting for each parameter (`dynamic` rounding mode, `unknown`
+    dynamic rounding mode, `masked` exception mode, and, when exceptions are not
+    masked, `true` for both `strict_snan` and `strict_except`) is canonically
+    represented as an unset parameter. Constructing an attribute whose
+    parameters are all set to their defaults therefore yields the same
+    canonical, empty attribute as `#llvm.fenv<>`.
+
+    Carrying the (possibly empty) attribute is *not* the same as having no
+    attribute at all. An operation that carries the attribute is lowered to the
+    corresponding constrained intrinsic, even when every parameter is at its
----------------
adams381 wrote:

The attribute doc says carrying `#llvm.fenv` lowers to the constrained intrinsic "even when every parameter is at its default value," and the binop path follows that (`@empty_fenv` -> `constrained.fadd ... fpexcept.ignore`). The masked `fcmp` path doesn't -- `@cmp_masked` drops to a plain `fcmp`. It's harmless (a masked compare has no exception state to preserve and rounding doesn't reach compares), so I'd just carve `fcmp` out of that sentence in the description rather than change the lowering.


https://github.com/llvm/llvm-project/pull/205158


More information about the Mlir-commits mailing list