[flang-commits] [flang] 000de66 - [flang] Use mlir complex dialect for supported operations

David Truby via flang-commits flang-commits at lists.llvm.org
Wed Oct 26 05:38:37 PDT 2022


Author: David Truby
Date: 2022-10-26T12:37:15Z
New Revision: 000de66649110bc3e0e7cc7d353f3d30c656bcb2

URL: https://github.com/llvm/llvm-project/commit/000de66649110bc3e0e7cc7d353f3d30c656bcb2
DIFF: https://github.com/llvm/llvm-project/commit/000de66649110bc3e0e7cc7d353f3d30c656bcb2.diff

LOG: [flang] Use mlir complex dialect for supported operations

This patch lowers the complex operations supported by the MLIR complex
dialect to those operations rather than libm. When the math runtime flag
is set to precise, libm lowering is used instead.

Differential Revision: https://reviews.llvm.org/D135882

Added: 
    

Modified: 
    flang/include/flang/Optimizer/Support/InitFIR.h
    flang/lib/Lower/IntrinsicCall.cpp
    flang/lib/Optimizer/CodeGen/CodeGen.cpp
    flang/test/Lower/Intrinsics/abs.f90
    flang/test/Lower/Intrinsics/exp.f90
    flang/test/Lower/Intrinsics/log.f90
    flang/test/Lower/math-lowering.f90
    flang/test/Lower/power-operator.f90
    flang/test/Lower/sqrt.f90
    flang/test/Lower/trigonometric-intrinsics.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/Support/InitFIR.h b/flang/include/flang/Optimizer/Support/InitFIR.h
index 434556edb32ee..bbc50dcec2e73 100644
--- a/flang/include/flang/Optimizer/Support/InitFIR.h
+++ b/flang/include/flang/Optimizer/Support/InitFIR.h
@@ -17,6 +17,7 @@
 #include "flang/Optimizer/HLFIR/HLFIRDialect.h"
 #include "mlir/Conversion/Passes.h"
 #include "mlir/Dialect/Affine/Passes.h"
+#include "mlir/Dialect/Complex/IR/Complex.h"
 #include "mlir/InitAllDialects.h"
 #include "mlir/Pass/Pass.h"
 #include "mlir/Pass/PassRegistry.h"
@@ -30,7 +31,8 @@ namespace fir::support {
       mlir::acc::OpenACCDialect, mlir::omp::OpenMPDialect,                     \
       mlir::scf::SCFDialect, mlir::arith::ArithDialect,                        \
       mlir::cf::ControlFlowDialect, mlir::func::FuncDialect,                   \
-      mlir::vector::VectorDialect, mlir::math::MathDialect
+      mlir::vector::VectorDialect, mlir::math::MathDialect,                    \
+      mlir::complex::ComplexDialect
 
 // The definitive list of dialects used by flang.
 #define FLANG_DIALECT_LIST                                                     \

diff  --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp
index c45270dc44d40..0184352336684 100644
--- a/flang/lib/Lower/IntrinsicCall.cpp
+++ b/flang/lib/Lower/IntrinsicCall.cpp
@@ -35,6 +35,7 @@
 #include "flang/Optimizer/Dialect/FIROpsSupport.h"
 #include "flang/Optimizer/Support/FatalError.h"
 #include "flang/Runtime/entry-names.h"
+#include "mlir/Dialect/Complex/IR/Complex.h"
 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
 #include "mlir/Dialect/Math/IR/Math.h"
 #include "llvm/Support/CommandLine.h"
@@ -1084,6 +1085,12 @@ llvm::cl::opt<MathRuntimeVersion> mathRuntimeVersion(
         clEnumValN(preciseVersion, "precise", "use precise runtime behavior")),
     llvm::cl::init(fastVersion));
 
+static llvm::cl::opt<bool>
+    disableMlirComplex("disable-mlir-complex",
+                       llvm::cl::desc("Use libm instead of the MLIR complex "
+                                      "dialect to lower complex operations"),
+                       llvm::cl::init(false));
+
 struct RuntimeFunction {
   // llvm::StringRef comparison operator are not constexpr, so use string_view.
   using Key = std::string_view;
@@ -1320,6 +1327,49 @@ static mlir::Value genMathOp(fir::FirOpBuilder &builder, mlir::Location loc,
   return result;
 }
 
+template <typename T>
+static mlir::Value genComplexMathOp(fir::FirOpBuilder &builder,
+                                    mlir::Location loc,
+                                    llvm::StringRef mathLibFuncName,
+                                    mlir::FunctionType mathLibFuncType,
+                                    llvm::ArrayRef<mlir::Value> args) {
+  mlir::Value result;
+  if (disableMlirComplex ||
+      (mathRuntimeVersion == preciseVersion && !mathLibFuncName.empty())) {
+    result = genLibCall(builder, loc, mathLibFuncName, mathLibFuncType, args);
+    LLVM_DEBUG(result.dump(); llvm::dbgs() << "\n");
+    return result;
+  }
+
+  LLVM_DEBUG(llvm::dbgs() << "Generating '" << mathLibFuncName
+                          << "' operation with type ";
+             mathLibFuncType.dump(); llvm::dbgs() << "\n");
+  auto type = mathLibFuncType.getInput(0).cast<fir::ComplexType>();
+  auto kind = type.getElementType().cast<fir::RealType>().getFKind();
+  auto realTy = builder.getRealType(kind);
+  auto mComplexTy = mlir::ComplexType::get(realTy);
+
+  llvm::SmallVector<mlir::Value, 2> cargs;
+  for (const mlir::Value &arg : args) {
+    // Convert the fir.complex to a mlir::complex
+    cargs.push_back(builder.createConvert(loc, mComplexTy, arg));
+  }
+
+  // Builder expects an extra return type to be provided if 
diff erent to
+  // the argument types for an operation
+  if constexpr (T::template hasTrait<
+                    mlir::OpTrait::SameOperandsAndResultType>()) {
+    result = builder.create<T>(loc, cargs);
+    result = builder.createConvert(loc, mathLibFuncType.getResult(0), result);
+  } else {
+    result = builder.create<T>(loc, realTy, cargs);
+    result = builder.createConvert(loc, mathLibFuncType.getResult(0), result);
+  }
+
+  LLVM_DEBUG(result.dump(); llvm::dbgs() << "\n");
+  return result;
+}
+
 /// Mapping between mathematical intrinsic operations and MLIR operations
 /// of some appropriate dialect (math, complex, etc.) or libm calls.
 /// TODO: support remaining Fortran math intrinsics.
@@ -1330,8 +1380,10 @@ static constexpr MathOperation mathOperations[] = {
     {"abs", "fabs", genF64F64FuncType, genMathOp<mlir::math::AbsFOp>},
     {"abs", "llvm.fabs.f128", genF128F128FuncType,
      genMathOp<mlir::math::AbsFOp>},
-    {"abs", "cabsf", genF32ComplexFuncType, genLibCall},
-    {"abs", "cabs", genF64ComplexFuncType, genLibCall},
+    {"abs", "cabsf", genF32ComplexFuncType,
+     genComplexMathOp<mlir::complex::AbsOp>},
+    {"abs", "cabs", genF64ComplexFuncType,
+     genComplexMathOp<mlir::complex::AbsOp>},
     {"acos", "acosf", genF32F32FuncType, genLibCall},
     {"acos", "acos", genF64F64FuncType, genLibCall},
     {"acos", "cacosf", genComplexComplexFuncType<4>, genLibCall},
@@ -1386,8 +1438,10 @@ static constexpr MathOperation mathOperations[] = {
     {"ceil", "ceil", genF64F64FuncType, genMathOp<mlir::math::CeilOp>},
     {"cos", "cosf", genF32F32FuncType, genMathOp<mlir::math::CosOp>},
     {"cos", "cos", genF64F64FuncType, genMathOp<mlir::math::CosOp>},
-    {"cos", "ccosf", genComplexComplexFuncType<4>, genLibCall},
-    {"cos", "ccos", genComplexComplexFuncType<8>, genLibCall},
+    {"cos", "ccosf", genComplexComplexFuncType<4>,
+     genComplexMathOp<mlir::complex::CosOp>},
+    {"cos", "ccos", genComplexComplexFuncType<8>,
+     genComplexMathOp<mlir::complex::CosOp>},
     {"cosh", "coshf", genF32F32FuncType, genLibCall},
     {"cosh", "cosh", genF64F64FuncType, genLibCall},
     {"cosh", "ccoshf", genComplexComplexFuncType<4>, genLibCall},
@@ -1398,8 +1452,10 @@ static constexpr MathOperation mathOperations[] = {
     {"erfc", "erfc", genF64F64FuncType, genLibCall},
     {"exp", "expf", genF32F32FuncType, genMathOp<mlir::math::ExpOp>},
     {"exp", "exp", genF64F64FuncType, genMathOp<mlir::math::ExpOp>},
-    {"exp", "cexpf", genComplexComplexFuncType<4>, genLibCall},
-    {"exp", "cexp", genComplexComplexFuncType<8>, genLibCall},
+    {"exp", "cexpf", genComplexComplexFuncType<4>,
+     genComplexMathOp<mlir::complex::ExpOp>},
+    {"exp", "cexp", genComplexComplexFuncType<8>,
+     genComplexMathOp<mlir::complex::ExpOp>},
     // math::FloorOp returns a real, while Fortran FLOOR returns integer.
     {"floor", "floorf", genF32F32FuncType, genMathOp<mlir::math::FloorOp>},
     {"floor", "floor", genF64F64FuncType, genMathOp<mlir::math::FloorOp>},
@@ -1409,8 +1465,10 @@ static constexpr MathOperation mathOperations[] = {
     {"hypot", "hypot", genF64F64F64FuncType, genLibCall},
     {"log", "logf", genF32F32FuncType, genMathOp<mlir::math::LogOp>},
     {"log", "log", genF64F64FuncType, genMathOp<mlir::math::LogOp>},
-    {"log", "clogf", genComplexComplexFuncType<4>, genLibCall},
-    {"log", "clog", genComplexComplexFuncType<8>, genLibCall},
+    {"log", "clogf", genComplexComplexFuncType<4>,
+     genComplexMathOp<mlir::complex::LogOp>},
+    {"log", "clog", genComplexComplexFuncType<8>,
+     genComplexMathOp<mlir::complex::LogOp>},
     {"log10", "log10f", genF32F32FuncType, genMathOp<mlir::math::Log10Op>},
     {"log10", "log10", genF64F64FuncType, genMathOp<mlir::math::Log10Op>},
     {"log_gamma", "lgammaf", genF32F32FuncType, genLibCall},
@@ -1426,8 +1484,10 @@ static constexpr MathOperation mathOperations[] = {
     {"pow", {}, genIntIntIntFuncType<64>, genMathOp<mlir::math::IPowIOp>},
     {"pow", "powf", genF32F32F32FuncType, genMathOp<mlir::math::PowFOp>},
     {"pow", "pow", genF64F64F64FuncType, genMathOp<mlir::math::PowFOp>},
-    {"pow", "cpowf", genComplexComplexComplexFuncType<4>, genLibCall},
-    {"pow", "cpow", genComplexComplexComplexFuncType<8>, genLibCall},
+    {"pow", "cpowf", genComplexComplexComplexFuncType<4>,
+     genComplexMathOp<mlir::complex::PowOp>},
+    {"pow", "cpow", genComplexComplexComplexFuncType<8>,
+     genComplexMathOp<mlir::complex::PowOp>},
     // TODO: add PowIOp in math and complex dialects.
     {"pow", "llvm.powi.f32.i32", genF32F32IntFuncType<32>, genLibCall},
     {"pow", "llvm.powi.f64.i32", genF64F64IntFuncType<32>, genLibCall},
@@ -1449,24 +1509,32 @@ static constexpr MathOperation mathOperations[] = {
      genMathOp<mlir::math::CopySignOp>},
     {"sin", "sinf", genF32F32FuncType, genMathOp<mlir::math::SinOp>},
     {"sin", "sin", genF64F64FuncType, genMathOp<mlir::math::SinOp>},
-    {"sin", "csinf", genComplexComplexFuncType<4>, genLibCall},
-    {"sin", "csin", genComplexComplexFuncType<8>, genLibCall},
+    {"sin", "csinf", genComplexComplexFuncType<4>,
+     genComplexMathOp<mlir::complex::SinOp>},
+    {"sin", "csin", genComplexComplexFuncType<8>,
+     genComplexMathOp<mlir::complex::SinOp>},
     {"sinh", "sinhf", genF32F32FuncType, genLibCall},
     {"sinh", "sinh", genF64F64FuncType, genLibCall},
     {"sinh", "csinhf", genComplexComplexFuncType<4>, genLibCall},
     {"sinh", "csinh", genComplexComplexFuncType<8>, genLibCall},
     {"sqrt", "sqrtf", genF32F32FuncType, genMathOp<mlir::math::SqrtOp>},
     {"sqrt", "sqrt", genF64F64FuncType, genMathOp<mlir::math::SqrtOp>},
-    {"sqrt", "csqrtf", genComplexComplexFuncType<4>, genLibCall},
-    {"sqrt", "csqrt", genComplexComplexFuncType<8>, genLibCall},
+    {"sqrt", "csqrtf", genComplexComplexFuncType<4>,
+     genComplexMathOp<mlir::complex::SqrtOp>},
+    {"sqrt", "csqrt", genComplexComplexFuncType<8>,
+     genComplexMathOp<mlir::complex::SqrtOp>},
     {"tan", "tanf", genF32F32FuncType, genMathOp<mlir::math::TanOp>},
     {"tan", "tan", genF64F64FuncType, genMathOp<mlir::math::TanOp>},
-    {"tan", "ctanf", genComplexComplexFuncType<4>, genLibCall},
-    {"tan", "ctan", genComplexComplexFuncType<8>, genLibCall},
+    {"tan", "ctanf", genComplexComplexFuncType<4>,
+     genComplexMathOp<mlir::complex::TanOp>},
+    {"tan", "ctan", genComplexComplexFuncType<8>,
+     genComplexMathOp<mlir::complex::TanOp>},
     {"tanh", "tanhf", genF32F32FuncType, genMathOp<mlir::math::TanhOp>},
     {"tanh", "tanh", genF64F64FuncType, genMathOp<mlir::math::TanhOp>},
-    {"tanh", "ctanhf", genComplexComplexFuncType<4>, genLibCall},
-    {"tanh", "ctanh", genComplexComplexFuncType<8>, genLibCall},
+    {"tanh", "ctanhf", genComplexComplexFuncType<4>,
+     genComplexMathOp<mlir::complex::TanhOp>},
+    {"tanh", "ctanh", genComplexComplexFuncType<8>,
+     genComplexMathOp<mlir::complex::TanhOp>},
 };
 
 // This helper class computes a "distance" between two function types.

diff  --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 126f68848a84c..23745a7a136bd 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -20,6 +20,8 @@
 #include "flang/Optimizer/Support/TypeCode.h"
 #include "flang/Semantics/runtime-type-info.h"
 #include "mlir/Conversion/ArithToLLVM/ArithToLLVM.h"
+#include "mlir/Conversion/ComplexToLLVM/ComplexToLLVM.h"
+#include "mlir/Conversion/ComplexToStandard/ComplexToStandard.h"
 #include "mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h"
 #include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"
 #include "mlir/Conversion/LLVMCommon/Pattern.h"
@@ -3535,6 +3537,7 @@ class FIRToLLVMLowering
     // as passes here.
     mlir::OpPassManager mathConvertionPM("builtin.module");
     mathConvertionPM.addPass(mlir::createConvertMathToFuncsPass());
+    mathConvertionPM.addPass(mlir::createConvertComplexToStandardPass());
     if (mlir::failed(runPipeline(mathConvertionPM, mod)))
       return signalPassFailure();
 
@@ -3599,6 +3602,7 @@ class FIRToLLVMLowering
     // when late math lowering mode is used, into llvm dialect.
     mlir::populateMathToLLVMConversionPatterns(typeConverter, pattern);
     mlir::populateMathToLibmConversionPatterns(pattern, /*benefit=*/0);
+    mlir::populateComplexToLLVMConversionPatterns(typeConverter, pattern);
     mlir::ConversionTarget target{*context};
     target.addLegalDialect<mlir::LLVM::LLVMDialect>();
     // The OpenMP dialect is legal for Operations without regions, for those

diff  --git a/flang/test/Lower/Intrinsics/abs.f90 b/flang/test/Lower/Intrinsics/abs.f90
index 52b5ff4baf0a7..11db7c650a895 100644
--- a/flang/test/Lower/Intrinsics/abs.f90
+++ b/flang/test/Lower/Intrinsics/abs.f90
@@ -1,5 +1,9 @@
-! RUN: bbc -emit-fir %s -o - | FileCheck %s
-! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+! RUN: bbc -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-FAST"
+! RUN: bbc -emit-fir --math-runtime=precise %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
+! RUN: bbc --disable-mlir-complex -emit-fir %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-FAST"
+! RUN: %flang_fc1 -emit-fir -mllvm --math-runtime=precise %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
+! RUN: %flang_fc1 -emit-fir -mllvm --disable-mlir-complex %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
 
 ! Test abs intrinsic for various types (int, float, complex)
 
@@ -90,25 +94,29 @@ subroutine abs_testr16(a, b)
   b = abs(a)
 end subroutine
 
-! CHECK-LABEL: func @_QPabs_testzr(
-! CHECK-SAME:  %[[VAL_0:.*]]: !fir.ref<!fir.complex<4>>{{.*}}, %[[VAL_1:.*]]: !fir.ref<f32>{{.*}}) {
+! CMPLX-LABEL: func @_QPabs_testzr(
+! CMPLX-SAME:  %[[VAL_0:.*]]: !fir.ref<!fir.complex<4>>{{.*}}, %[[VAL_1:.*]]: !fir.ref<f32>{{.*}}) {
 subroutine abs_testzr(a, b)
-! CHECK:  %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.complex<4>>
-! CHECK:  %[[VAL_3:.*]] = fir.call @cabsf(%[[VAL_2]]) : (!fir.complex<4>) -> f32
-! CHECK:  fir.store %[[VAL_3]] to %[[VAL_1]] : !fir.ref<f32>
-! CHECK:  return
+! CMPLX:  %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.complex<4>>
+! CMPLX-FAST: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.complex<4>) -> complex<f32>
+! CMPLX-FAST: %[[VAL_4:.*]] = complex.abs %[[VAL_3]] : complex<f32>
+! CMPLX-PRECISE:  %[[VAL_4:.*]] = fir.call @cabsf(%[[VAL_2]]) : (!fir.complex<4>) -> f32
+! CMPLX:  fir.store %[[VAL_4]] to %[[VAL_1]] : !fir.ref<f32>
+! CMPLX:  return
   complex :: a
   real :: b
   b = abs(a)
 end subroutine abs_testzr
 
-! CHECK-LABEL: func @_QPabs_testzd(
-! CHECK-SAME:  %[[VAL_0:.*]]: !fir.ref<!fir.complex<8>>{{.*}}, %[[VAL_1:.*]]: !fir.ref<f64>{{.*}}) {
+! CMPLX-LABEL: func @_QPabs_testzd(
+! CMPLX-SAME:  %[[VAL_0:.*]]: !fir.ref<!fir.complex<8>>{{.*}}, %[[VAL_1:.*]]: !fir.ref<f64>{{.*}}) {
 subroutine abs_testzd(a, b)
-! CHECK:  %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.complex<8>>
-! CHECK:  %[[VAL_3:.*]] = fir.call @cabs(%[[VAL_2]]) : (!fir.complex<8>) -> f64
-! CHECK:  fir.store %[[VAL_3]] to %[[VAL_1]] : !fir.ref<f64>
-! CHECK:  return
+! CMPLX:  %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.complex<8>>
+! CMPLX-FAST: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.complex<8>) -> complex<f64>
+! CMPLX-FAST: %[[VAL_4:.*]] = complex.abs %[[VAL_3]] : complex<f64>
+! CMPLX-PRECISE:  %[[VAL_4:.*]] = fir.call @cabs(%[[VAL_2]]) : (!fir.complex<8>) -> f64
+! CMPLX:  fir.store %[[VAL_4]] to %[[VAL_1]] : !fir.ref<f64>
+! CMPLX:  return
   complex(kind=8) :: a
   real(kind=8) :: b
   b = abs(a)

diff  --git a/flang/test/Lower/Intrinsics/exp.f90 b/flang/test/Lower/Intrinsics/exp.f90
index 6ddd56ce15be9..9fb1557d993d8 100644
--- a/flang/test/Lower/Intrinsics/exp.f90
+++ b/flang/test/Lower/Intrinsics/exp.f90
@@ -1,5 +1,9 @@
-! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s
-! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s
+! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-FAST"
+! RUN: bbc -emit-fir --math-runtime=precise -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
+! RUN: bbc -emit-fir --disable-mlir-complex -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
+! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-FAST"
+! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics -mllvm --math-runtime=precise %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
+! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics -mllvm --disable-mlir-complex %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
 
 ! CHECK-LABEL: exp_testr
 ! CHECK-SAME: (%[[AREF:.*]]: !fir.ref<f32> {{.*}}, %[[BREF:.*]]: !fir.ref<f32> {{.*}})
@@ -51,12 +55,18 @@ subroutine exp_testcd(a, b)
 ! CHECK: %[[RESULT64_OUTLINE:.*]] = math.exp %[[ARG64_OUTLINE]] : f64
 ! CHECK: return %[[RESULT64_OUTLINE]] : f64
 
-! CHECK-LABEL: private @fir.exp.z4.z4
-! CHECK-SAME: (%[[ARG32_OUTLINE]]: !fir.complex<4>) -> !fir.complex<4>
-! CHECK: %[[RESULT32_OUTLINE]] = fir.call @cexpf(%[[ARG32_OUTLINE]]) : (!fir.complex<4>) -> !fir.complex<4>
-! CHECK: return %[[RESULT32_OUTLINE]] : !fir.complex<4>
+! CMPLX-LABEL: private @fir.exp.z4.z4
+! CMPLX-SAME: (%[[ARG32_OUTLINE:.*]]: !fir.complex<4>) -> !fir.complex<4>
+! CMPLX-FAST: %[[C:.*]] = fir.convert %[[ARG32_OUTLINE]] : (!fir.complex<4>) -> complex<f32>
+! CMPLX-FAST: %[[E:.*]] = complex.exp %[[C]] : complex<f32>
+! CMPLX-FAST: %[[RESULT32_OUTLINE:.*]] = fir.convert %[[E]] : (complex<f32>) -> !fir.complex<4>
+! CMPLX-PRECISE: %[[RESULT32_OUTLINE:.*]] = fir.call @cexpf(%[[ARG32_OUTLINE]]) : (!fir.complex<4>) -> !fir.complex<4>
+! CMPLX: return %[[RESULT32_OUTLINE]] : !fir.complex<4>
 
-! CHECK-LABEL: private @fir.exp.z8.z8
-! CHECK-SAME: (%[[ARG64_OUTLINE]]: !fir.complex<8>) -> !fir.complex<8>
-! CHECK: %[[RESULT64_OUTLINE]] = fir.call @cexp(%[[ARG64_OUTLINE]]) : (!fir.complex<8>) -> !fir.complex<8>
-! CHECK: return %[[RESULT64_OUTLINE]] : !fir.complex<8>
+! CMPLX-LABEL: private @fir.exp.z8.z8
+! CMPLX-SAME: (%[[ARG64_OUTLINE:.*]]: !fir.complex<8>) -> !fir.complex<8>
+! CMPLX-FAST: %[[C:.*]] = fir.convert %[[ARG64_OUTLINE]] : (!fir.complex<8>) -> complex<f64>
+! CMPLX-FAST: %[[E:.*]] = complex.exp %[[C]] : complex<f64>
+! CMPLX-FAST: %[[RESULT64_OUTLINE:.*]] = fir.convert %[[E]] : (complex<f64>) -> !fir.complex<8>
+! CMPLX-PRECISE: %[[RESULT64_OUTLINE:.*]] = fir.call @cexp(%[[ARG64_OUTLINE]]) : (!fir.complex<8>) -> !fir.complex<8>
+! CMPLX: return %[[RESULT64_OUTLINE]] : !fir.complex<8>

diff  --git a/flang/test/Lower/Intrinsics/log.f90 b/flang/test/Lower/Intrinsics/log.f90
index 3c35a3ac661a0..80376a95b3972 100644
--- a/flang/test/Lower/Intrinsics/log.f90
+++ b/flang/test/Lower/Intrinsics/log.f90
@@ -1,5 +1,9 @@
-! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s
-! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s
+! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-FAST"
+! RUN: bbc -emit-fir --math-runtime=precise -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
+! RUN: bbc -emit-fir --disable-mlir-complex -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
+! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-FAST"
+! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics -mllvm --math-runtime=precise %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
+! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics -mllvm --disable-mlir-complex %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-PRECISE"
 
 ! CHECK-LABEL: log_testr
 ! CHECK-SAME: (%[[AREF:.*]]: !fir.ref<f32> {{.*}}, %[[BREF:.*]]: !fir.ref<f32> {{.*}})
@@ -71,15 +75,21 @@ subroutine log10_testd(a, b)
 ! CHECK: %[[RESULT64_OUTLINE:.*]] = math.log %[[ARG64_OUTLINE]] : f64
 ! CHECK: return %[[RESULT64_OUTLINE]] : f64
 
-! CHECK-LABEL: private @fir.log.z4.z4
-! CHECK-SAME: (%[[ARG32_OUTLINE]]: !fir.complex<4>) -> !fir.complex<4>
-! CHECK: %[[RESULT32_OUTLINE]] = fir.call @clogf(%[[ARG32_OUTLINE]]) : (!fir.complex<4>) -> !fir.complex<4>
-! CHECK: return %[[RESULT32_OUTLINE]] : !fir.complex<4>
+! CMPLX-LABEL: private @fir.log.z4.z4
+! CMPLX-SAME: (%[[ARG32_OUTLINE:.*]]: !fir.complex<4>) -> !fir.complex<4>
+! CMPLX-FAST: %[[C:.*]] = fir.convert %[[ARG32_OUTLINE]] : (!fir.complex<4>) -> complex<f32>
+! CMPLX-FAST: %[[E:.*]] = complex.log %[[C]] : complex<f32>
+! CMPLX-FAST: %[[RESULT32_OUTLINE:.*]] = fir.convert %[[E]] : (complex<f32>) -> !fir.complex<4>
+! CMPLX-PRECISE: %[[RESULT32_OUTLINE:.*]] = fir.call @clogf(%[[ARG32_OUTLINE]]) : (!fir.complex<4>) -> !fir.complex<4>
+! CMPLX: return %[[RESULT32_OUTLINE]] : !fir.complex<4>
 
-! CHECK-LABEL: private @fir.log.z8.z8
-! CHECK-SAME: (%[[ARG64_OUTLINE]]: !fir.complex<8>) -> !fir.complex<8>
-! CHECK: %[[RESULT64_OUTLINE]] = fir.call @clog(%[[ARG64_OUTLINE]]) : (!fir.complex<8>) -> !fir.complex<8>
-! CHECK: return %[[RESULT64_OUTLINE]] : !fir.complex<8>
+! CMPLX-LABEL: private @fir.log.z8.z8
+! CMPLX-SAME: (%[[ARG64_OUTLINE:.*]]: !fir.complex<8>) -> !fir.complex<8>
+! CMPLX-FAST: %[[C:.*]] = fir.convert %[[ARG64_OUTLINE]] : (!fir.complex<8>) -> complex<f64>
+! CMPLX-FAST: %[[E:.*]] = complex.log %[[C]] : complex<f64>
+! CMPLX-FAST: %[[RESULT64_OUTLINE:.*]] = fir.convert %[[E]] : (complex<f64>) -> !fir.complex<8>
+! CMPLX-PRECISE: %[[RESULT64_OUTLINE:.*]] = fir.call @clog(%[[ARG64_OUTLINE]]) : (!fir.complex<8>) -> !fir.complex<8>
+! CMPLX: return %[[RESULT64_OUTLINE]] : !fir.complex<8>
 
 ! CHECK-LABEL: private @fir.log10.f32.f32
 ! CHECK-SAME: (%[[ARG32_OUTLINE:.*]]: f32) -> f32

diff  --git a/flang/test/Lower/math-lowering.f90 b/flang/test/Lower/math-lowering.f90
index 558c44c556e49..7d9bf7c0c2a86 100644
--- a/flang/test/Lower/math-lowering.f90
+++ b/flang/test/Lower/math-lowering.f90
@@ -43,7 +43,9 @@ function test_complex4(c)
 end function
 
 ! ALL-LABEL: @_QPtest_complex4
-! ALL: {{%[A-Za-z0-9._]+}} = fir.call @cabsf({{%[A-Za-z0-9._]+}}) : (!fir.complex<4>) -> f32
+! FAST: {{%[A-Za-z0-9._]+}} = complex.abs {{%[A-Za-z0-9._]+}} : complex<f32>
+! RELAXED: {{%[A-Za-z0-9._]+}} = complex.abs {{%[A-Za-z0-9._]+}} : complex<f32>
+! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @cabsf({{%[A-Za-z0-9._]+}}) : (!fir.complex<4>) -> f32
 
 function test_complex8(c)
   complex(8) :: c, test_complex8
@@ -51,7 +53,9 @@ function test_complex8(c)
 end function
 
 ! ALL-LABEL: @_QPtest_complex8
-! ALL: {{%[A-Za-z0-9._]+}} = fir.call @cabs({{%[A-Za-z0-9._]+}}) : (!fir.complex<8>) -> f64
+! FAST: {{%[A-Za-z0-9._]+}} = complex.abs {{%[A-Za-z0-9._]+}} : complex<f64>
+! RELAXED: {{%[A-Za-z0-9._]+}} = complex.abs {{%[A-Za-z0-9._]+}} : complex<f64>
+! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @cabs({{%[A-Za-z0-9._]+}}) : (!fir.complex<8>) -> f64
 
 //--- aint.f90
 ! RUN: bbc -emit-fir %t/aint.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL %t/aint.f90

diff  --git a/flang/test/Lower/power-operator.f90 b/flang/test/Lower/power-operator.f90
index a92f2b31979d9..867830f959aa0 100644
--- a/flang/test/Lower/power-operator.f90
+++ b/flang/test/Lower/power-operator.f90
@@ -1,4 +1,9 @@
-! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: bbc -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX-FAST"
+! RUN: bbc --math-runtime=precise -emit-fir %s -o - | FileCheck %s --check-prefixes="CMPLX-PRECISE"
+! RUN: bbc --disable-mlir-complex -emit-fir %s -o - | FileCheck %s --check-prefixes="CMPLX-PRECISE"
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX-FAST"
+! RUN: %flang_fc1 -emit-fir -mllvm --math-runtime=precise %s -o - | FileCheck %s --check-prefixes="CMPLX-PRECISE"
+! RUN: %flang_fc1 -emit-fir -mllvm --disable-mlir-complex %s -o - | FileCheck %s --check-prefixes="CMPLX-PRECISE"
 
 ! Test power operation lowering
 
@@ -121,13 +126,15 @@ subroutine pow_c8_i8(x, y, z)
 subroutine pow_c4_c4(x, y, z)
   complex :: x, y, z
   z = x ** y
-  ! CHECK: call @cpowf
+  ! CMPLX-FAST: complex.pow %{{.*}}, %{{.*}} : complex<f32>
+  ! CMPLX-PRECISE: call @cpowf
 end subroutine
 
 ! CHECK-LABEL: pow_c8_c8
 subroutine pow_c8_c8(x, y, z)
   complex(8) :: x, y, z
   z = x ** y
-  ! CHECK: call @cpow
+  ! CMPLX-FAST: complex.pow %{{.*}}, %{{.*}} : complex<f64>
+  ! CMPLX-PRECISE: call @cpow
 end subroutine
 

diff  --git a/flang/test/Lower/sqrt.f90 b/flang/test/Lower/sqrt.f90
index e4537c54d50ad..4b4bc9e3ff52a 100644
--- a/flang/test/Lower/sqrt.f90
+++ b/flang/test/Lower/sqrt.f90
@@ -1,5 +1,9 @@
-! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s
-! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s
+! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX-FAST"
+! RUN: bbc --math-runtime=precise -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX-PRECISE"
+! RUN: bbc --disable-mlir-complex -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX-PRECISE"
+! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX-FAST"
+! RUN: %flang_fc1 -emit-fir -mllvm --math-runtime=precise -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX-PRECISE"
+! RUN: %flang_fc1 -emit-fir -mllvm --disable-mlir-complex -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX-PRECISE"
 
 ! CHECK-LABEL: sqrt_testr
 subroutine sqrt_testr(a, b)
@@ -36,7 +40,9 @@ subroutine sqrt_testcd(z)
 ! CHECK: math.sqrt %{{.*}} : f64
 
 ! CHECK-LABEL: func private @fir.sqrt.z4.z4
-! CHECK: fir.call @csqrtf
+! CMPLX-FAST: complex.sqrt %{{.*}} : complex<f32>
+! CMPLX-PRECISE: fir.call @csqrtf
 
 ! CHECK-LABEL: @fir.sqrt.z8.z8
-! CHECK: fir.call @csqrt
+! CMPLX-FAST: complex.sqrt %{{.*}} : complex<f64>
+! CMPLX-PRECISE: fir.call @csqrt

diff  --git a/flang/test/Lower/trigonometric-intrinsics.f90 b/flang/test/Lower/trigonometric-intrinsics.f90
index 99b181281e205..e1e690c9ffd58 100644
--- a/flang/test/Lower/trigonometric-intrinsics.f90
+++ b/flang/test/Lower/trigonometric-intrinsics.f90
@@ -1,4 +1,5 @@
-! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s
+! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX-FAST"
+! RUN: bbc --math-runtime=precise -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX-PRECISE"
 ! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s
 
 ! CHECK-LABEL: tan_testr
@@ -176,10 +177,12 @@ subroutine sinh_testcd(z)
 ! CHECK: math.tan %{{.*}} : f64
 
 ! CHECK-LABEL: @fir.tan.z4.z4
-! CHECK: fir.call @ctanf
+! CMPLX-FAST: complex.tan %{{.*}} : complex<f32>
+! CMPLX-PRECISE: fir.call @ctanf
 
 ! CHECK-LABEL: @fir.tan.z8.z8
-! CHECK: fir.call @ctan
+! CMPLX-FAST: complex.tan %{{.*}} : complex<f64>
+! CMPLX-PRECISE: fir.call @ctan
 
 ! CHECK-LABEL: @fir.atan.f32.f32
 ! CHECK: math.atan %{{.*}} : f32
@@ -200,10 +203,12 @@ subroutine sinh_testcd(z)
 ! CHECK: math.cos %{{.*}} : f64
 
 ! CHECK-LABEL: @fir.cos.z4.z4
-! CHECK: fir.call @ccosf
+! CMPLX-FAST: complex.cos %{{.*}} : complex<f32>
+! CMPLX-PRECISE: fir.call @ccosf
 
 ! CHECK-LABEL: @fir.cos.z8.z8
-! CHECK: fir.call @ccos
+! CMPLX-FAST: complex.cos %{{.*}} : complex<f64>
+! CMPLX-PRECISE: fir.call @ccos
 
 ! CHECK-LABEL: @fir.cosh.f32.f32
 ! CHECK: fir.call {{.*}}cosh
@@ -224,10 +229,12 @@ subroutine sinh_testcd(z)
 ! CHECK: math.sin %{{.*}} : f64
 
 ! CHECK-LABEL: @fir.sin.z4.z4
-! CHECK: fir.call @csinf
+! CMPLX-FAST: complex.sin %{{.*}} : complex<f32>
+! CMPLX-PRECISE: fir.call @csinf
 
 ! CHECK-LABEL: @fir.sin.z8.z8
-! CHECK: fir.call @csin
+! CMPLX-FAST: complex.sin %{{.*}} : complex<f64>
+! CMPLX-PRECISE: fir.call @csin
 
 ! CHECK-LABEL: @fir.sinh.f32.f32
 ! CHECK: fir.call {{.*}}sinh


        


More information about the flang-commits mailing list