[RFC] Adding better support for higher precision floating-point

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.

Goal:
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.

Approaches:

  1. The whole enchilada. Add full support for higher precision floating point types. This proposal would add types f80 and 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.

  2. 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.

Thanks for the proposal Eric!

I’m +1 on the builtin float types supporting whatever APFloat supports.

I don’t know if you’ve seen, but !llvm.float is being replaced with the builtin float type. Extending the builtin float type coverage should allow for full replacement of all LLVM float types.

Bit of a nit here, but the standard dialect has no types in it. It uses the builtin types, which are part of the builtin dialect.

Yeah I’d also prefer that we just add f80 and f128 to MLIR in general. I don’t see any reason to exclude them.

I support this direction. Indeed, the LLVM dialect floating-point types are getting removed so there will be no diverging types on llvm.mlir.constant.

I knew this (using builtin types) was being discussed, but wasn’t sure that a decision had been made. Thanks for confirming this direction.

Sounds like adding f80 and f128 is the preferred approach. Good. :slight_smile:

Since this will be useful for Flang, I tried to put together a patch for this -> ⚙ D94737 [mlir] Add better support for f80 and f128