The LLVMIR dialect in MLIR currently has support for FastMath flags (nnan, ninf, nsz, …) that map directly to the LLVM equivalents for floating point instructions (e.g. fadd, fsub, …). I would argue that MLIR would benefit from supporting the FastMath concepts in other places, outside of the LLVMIR dialect. (More on the “where” in MLIR below.) Specifically:
- there may be target-specific IRs that are not LLVM IR (see Tensor Codegen Thoughts, MLIR ODM 2020/01/23, slide 6)
FastMathsemantics in many cases map directly to higher level constructs like vectors and tensors, and transformations may wish to leverage this behavior before lowering to theLLVMIRdialect.
There are already some cases where fast-math-related floating point behavior ambiguity exists (or did exist) in MLIR:
- Canonicalization of ‘x + (+0.0)’ in tosa
- conversion of
complex::MulOpinComplexToLLVM.cppadopts the “naive” finite math lowering approach that would result from fast-math optimizations, whereas the same conversion (to theArithmeticdialect) inComplexToStandard.cppgenerates the (dozens of) extra instructions to correctly handle Inf/Nan values
The documentation for the floating point instructions in the Arithmetic dialect (example here) suggest FastMath attributes as a “distant future” TODO.
Considerations:
It seems sensible to build on what LLVM and clang have done here.
- Initially, the MLIR
FastMathFlagswould be identical to theLLVMfast-mathflags. This would allow for straightforward lowering to LLVM IR. LLVMallowsfast-mathflags for floating point instructions (e.g.fadd,fmul,fdiv, …) as well as thephi,select, andcallinstructions (which, in MLIR, are not in thearithdialect). However, it seems feasible to restrict the scope of theFastMathFlagsattribute to thearithdialect:- LLVM optimizations to
callinstructions withfast-mathflags seemed to be limited to optimizations that leverage specific knowledge of the meaning of LLVM intrinsics or known library calls (e.q.sqrt()) that may be inlined/LTO. It seems that the existing MLIR framework can accomplish similar optimizations on known functions (if desired), without requiringfast-mathattribute support for thestd.calloperation. - There is no corresponding
phinode in MLIR - LLVM does perform some optimizations on
selectinstructions with floating point arguments whenfast-mathflags are present. MLIR has aselectoperation in thestddialect. In spite of this, I would think it makes more sense to confineFastMathFlagsto thearithdialect, as opposed to cluttering the to-be-replaced-at-some-pointstddialect.
- LLVM optimizations to
- Should MLIR have a.) a
fast-mathattribute with a default value of “no-fast-math-optimizations”, or b.) an optionalfast-mathattribute?- clang seems to have gone through some evolution in terms of interpreting an unset
fast-mathbit as “unspecified” vs. “intentionally unset to forbid optimizations.” It seems feasible in MLIR that pipelines could, for example, setfast-mathfor all operations without that don’t have the (optional) attribute present, and keep other (numerically sensitive) operations (that have a specificfast-mathattribute present) untouched. (An alternative with more granularity would be a set of optional boolean attributes.) I think that the optionalBitEnumAttrattribute approach would provide some flexibility.
- clang seems to have gone through some evolution in terms of interpreting an unset
Proposed changes:
- Creation of a
FastMathFlagsattribute type (more specifically, aBitEnumAttr) in thearithdialect - Additonal of an optional
FastMathFlagsattribute to floating point operations in thearithdialect - Addition of a
FastMathinterface to the floating point operations in thearithdialect, patterned after the existing interface in the LLVMIR. This interface would be used (primarily) to apply modifications to theFastMathFlagsfor operations that support it. - Development of passes that use the
FastMathFlagsInterfaceto add/modifyfast-mathflags for supporting operations - Progressive addition of
fast-math-aware transforms/folding implementations for floating pointarithoperations