9 Fortran includes support for complex number types and a set of operators and
10 intrinsics that work on these types. Some of those operations are complicated
11 and require runtime function calls to implement.
13 This document outlines a design for generating these operations using the MLIR
14 complex dialect while avoiding cross-platform ABI issues.
18 MLIR contains a complex dialect, similar to the Math dialect also used for
19 lowering some integer and floating point operations in Flang. Conversion between
20 fir.complex types and MLIR complex types is supported.
22 As a result at the FIR level, complex operations can be represented as
23 conversions from the fir.complex type to the equivalent MLIR complex type, use
24 of the MLIR operation and a conversion back.
26 This is similar to the way the math intrinsics are lowered, as proposed [here][1]
31 complex, intent(in) :: c
39 func.func @_QPpow_self(%arg0: !fir.ref<!fir.complex<4>>) -> !fir.complex<4> {
40 %0 = fir.alloca !fir.complex<4>
41 %1 = fir.load %arg0 : !fir.ref<!fir.complex<4>>
42 %2 = fir.load %arg0 : !fir.ref<!fir.complex<4>>
43 %3 = fir.convert %1 : (!fir.complex<4>) -> complex<f32>
44 %4 = fir.convert %2 : (!fir.complex<4>) -> complex<f32>
45 %5 = complex.pow %3, %4 : complex<f32>
46 %6 = fir.convert %5 : (complex<f32>) -> !fir.complex<4>
47 fir.store %6 to %0 : !fir.ref<!fir.complex<4>>
48 %7 = fir.load %0 : !fir.ref<!fir.complex<4>>
49 return %7 : !fir.complex<4>
53 Some operations are currently missing in the MLIR complex dialect that we would
54 want to use here, such as powi and the hyperbolic trigonometry functions.
55 For the missing operations we call directly to libm where possible, for powi
56 we provide an implementation in the flang runtime.
60 The MLIR complex dialect supports lowering either by emitting calls to the
61 complex functions in libm (ComplexToLibm), or through lowering to the standard
62 dialect (ComplexToStandard). However, as MLIR has no target awareness, the
63 lowering to libm functions suffers from ABI incompatibilities on some platforms.
64 As such the custom lowering to the standard dialect is used. This may be
65 something to revisit in future if performance could be improved by using the
68 Similarly to the numerical lowering through the math dialect, certain MLIR
69 optimisations could violate the precise floating point model, so when that is
70 requested lowering manually emits calls to libm, rather than going through the
73 The ComplexToStandard dialect does still call into libm for some floating
74 point math operations, however these don't have the same ABI issues as the
75 complex libm functions.
77 [1]: https://discourse.llvm.org/t/rfc-change-lowering-of-fortran-math-intrinsics/63971