This post is to hopefully start a conversation on higher precision floating-point value support.
The MLIR standard dialect currently supports a number of floating-point representation up to and including double precision. The MLIR LLVM-IR dialect nominally supports the representations found in LLVM, which include higher precisions such as the X86 80-bit format and quad precision. The flang (Fortran) front-end also supports KIND values for these higher precision floating-point values.
For the flang project, we’d like to bridge this gap, and allow a path from the flang front-end all the way through MLIR to LLVM (proper) that supports these extended precision types.
The whole enchilada. Add full support for higher precision floating point types. This proposal would add types
f128, which would extend the floating-point family of types beyond
f64. This option would make these types available not just to flang/Fortran but to any project that may want/need higher precision types.
Surgical. The FIR dialect already has its own parallel set of floating-point types and operations, so a more minimalist approach would be to focus strictly the point where this fails. Specifically, it is in the construction of a constant value:
// Floating point constant. %2 = llvm.mlir.constant(42.0 : f32) : !llvm.float
Somewhat subtly, this Op involves both an llvm-ir dialect type (
!llvm.float, for the Op itself) and a standard dialect type (
f32). Because the std dialect types are a subset and do not include the higher precision types, one cannot build an
llvm.mlir.constant for a value of type
f80, for example. Internally, the
FloatAttr has an
llvm::APFloat, which can represent the higher precision values. But this mix of a standard and an LLVM-IR dialect type has become an issue as they do not cover the same families of types.
Various approaches to a solution come to mind here. For argument’s sake, we’ll propose here the addition of a
mlir::LLVM::LLVMFloatAttr attribute class. This new attribute would be used in an
llvm.mlir.constant Op, subsuming
FloatAttr, but use the LLVM-IR dialect floating-point types and enforce consistency between the type of the Op and the type of the attribute value.
Obviously, there are many other solutions possible that range in complexity between the two approaches sketched above. It is also quite possible there is an even simpler solution that (2) suggests.