diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -572,10 +572,10 @@ llvm::cl::init(fastVersion)); static llvm::cl::opt - disableMlirComplex("disable-mlir-complex", - llvm::cl::desc("Use libm instead of the MLIR complex " - "dialect to lower complex operations"), - llvm::cl::init(false)); + forceMlirComplex("force-mlir-complex", + llvm::cl::desc("Force using MLIR complex operations " + "instead of libm complex operations"), + llvm::cl::init(false)); mlir::Value genLibCall(fir::FirOpBuilder &builder, mlir::Location loc, llvm::StringRef libFuncName, @@ -734,12 +734,19 @@ mlir::FunctionType mathLibFuncType, llvm::ArrayRef args) { mlir::Value result; - bool hasApproxFunc = mlir::arith::bitEnumContainsAny( + bool canUseApprox = mlir::arith::bitEnumContainsAny( builder.getFastMathFlags(), mlir::arith::FastMathFlags::afn); - if ((disableMlirComplex || !hasApproxFunc) && !mathLibFuncName.empty()) { - result = genLibCall(builder, loc, mathLibFuncName, mathLibFuncType, args); - LLVM_DEBUG(result.dump(); llvm::dbgs() << "\n"); - return result; + + // If we have libm functions, we can attempt to generate the more precise + // version of the complex math operation. + if (!mathLibFuncName.empty()) { + // If we enabled MLIR complex or can use approximate operations, we should + // NOT use libm. + if (!forceMlirComplex && !canUseApprox) { + result = genLibCall(builder, loc, mathLibFuncName, mathLibFuncType, args); + LLVM_DEBUG(result.dump(); llvm::dbgs() << "\n"); + return result; + } } LLVM_DEBUG(llvm::dbgs() << "Generating '" << mathLibFuncName diff --git a/flang/test/Lower/Intrinsics/abs.f90 b/flang/test/Lower/Intrinsics/abs.f90 --- a/flang/test/Lower/Intrinsics/abs.f90 +++ b/flang/test/Lower/Intrinsics/abs.f90 @@ -1,9 +1,9 @@ ! RUN: bbc -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-PRECISE" ! 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: bbc --force-mlir-complex -emit-fir %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-FAST" ! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-PRECISE" ! 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" +! RUN: %flang_fc1 -emit-fir -mllvm --force-mlir-complex %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-FAST" ! RUN: %flang_fc1 -fapprox-func -emit-fir %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-FAST" ! Test abs intrinsic for various types (int, float, complex) diff --git a/flang/test/Lower/Intrinsics/exp.f90 b/flang/test/Lower/Intrinsics/exp.f90 --- a/flang/test/Lower/Intrinsics/exp.f90 +++ b/flang/test/Lower/Intrinsics/exp.f90 @@ -1,10 +1,10 @@ ! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-PRECISE" ! 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: bbc -emit-fir --force-mlir-complex -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-FAST,CMPLX-MLIR" ! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-PRECISE" -! RUN: %flang_fc1 -fapprox-func -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-FAST" +! RUN: %flang_fc1 -fapprox-func -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-FAST,CMPLX-APPROX" ! 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" +! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics -mllvm --force-mlir-complex %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-FAST,CMPLX-MLIR" ! CHECK-LABEL: exp_testr ! CHECK-SAME: (%[[AREF:.*]]: !fir.ref {{.*}}, %[[BREF:.*]]: !fir.ref {{.*}}) @@ -56,8 +56,9 @@ ! CHECK: %[[RESULT64_OUTLINE:.*]] = math.exp %[[ARG64_OUTLINE]] fastmath : f64 ! CHECK: return %[[RESULT64_OUTLINE]] : f64 -! CMPLX-FAST-LABEL: private @fir.exp.contract_afn.z4.z4 +! CMPLX-APPROX-LABEL: private @fir.exp.contract_afn.z4.z4 ! CMPLX-PRECISE-LABEL: private @fir.exp.contract.z4.z4 +! CMPLX-MLIR-LABEL: private @fir.exp.contract.z4.z4 ! CMPLX-SAME: (%[[ARG32_OUTLINE:.*]]: !fir.complex<4>) -> !fir.complex<4> ! CMPLX-FAST: %[[C:.*]] = fir.convert %[[ARG32_OUTLINE]] : (!fir.complex<4>) -> complex ! CMPLX-FAST: %[[E:.*]] = complex.exp %[[C]] : complex @@ -65,8 +66,9 @@ ! CMPLX-PRECISE: %[[RESULT32_OUTLINE:.*]] = fir.call @cexpf(%[[ARG32_OUTLINE]]) fastmath : (!fir.complex<4>) -> !fir.complex<4> ! CMPLX: return %[[RESULT32_OUTLINE]] : !fir.complex<4> -! CMPLX-FAST-LABEL: private @fir.exp.contract_afn.z8.z8 +! CMPLX-APPROX-LABEL: private @fir.exp.contract_afn.z8.z8 ! CMPLX-PRECISE-LABEL: private @fir.exp.contract.z8.z8 +! CMPLX-MLIR-LABEL: private @fir.exp.contract.z8.z8 ! CMPLX-SAME: (%[[ARG64_OUTLINE:.*]]: !fir.complex<8>) -> !fir.complex<8> ! CMPLX-FAST: %[[C:.*]] = fir.convert %[[ARG64_OUTLINE]] : (!fir.complex<8>) -> complex ! CMPLX-FAST: %[[E:.*]] = complex.exp %[[C]] : complex diff --git a/flang/test/Lower/Intrinsics/log.f90 b/flang/test/Lower/Intrinsics/log.f90 --- a/flang/test/Lower/Intrinsics/log.f90 +++ b/flang/test/Lower/Intrinsics/log.f90 @@ -1,10 +1,10 @@ ! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-PRECISE" ! 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: bbc -emit-fir --force-mlir-complex -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-FAST,CMPLX-MLIR" ! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX,CMPLX-PRECISE" ! 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" -! RUN: %flang_fc1 -fapprox-func -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-FAST" +! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics -mllvm --force-mlir-complex %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-FAST,CMPLX-MLIR" +! RUN: %flang_fc1 -fapprox-func -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX,CMPLX-FAST,CMPLX-APPROX" ! CHECK-LABEL: log_testr ! CHECK-SAME: (%[[AREF:.*]]: !fir.ref {{.*}}, %[[BREF:.*]]: !fir.ref {{.*}}) @@ -76,8 +76,9 @@ ! CHECK: %[[RESULT64_OUTLINE:.*]] = math.log %[[ARG64_OUTLINE]] fastmath : f64 ! CHECK: return %[[RESULT64_OUTLINE]] : f64 -! CMPLX-FAST-LABEL: private @fir.log.contract_afn.z4.z4 +! CMPLX-APPROX-LABEL: private @fir.log.contract_afn.z4.z4 ! CMPLX-PRECISE-LABEL: private @fir.log.contract.z4.z4 +! CMPLX-MLIR-LABEL: private @fir.log.contract.z4.z4 ! CMPLX-SAME: (%[[ARG32_OUTLINE:.*]]: !fir.complex<4>) -> !fir.complex<4> ! CMPLX-FAST: %[[C:.*]] = fir.convert %[[ARG32_OUTLINE]] : (!fir.complex<4>) -> complex ! CMPLX-FAST: %[[E:.*]] = complex.log %[[C]] : complex @@ -85,8 +86,9 @@ ! CMPLX-PRECISE: %[[RESULT32_OUTLINE:.*]] = fir.call @clogf(%[[ARG32_OUTLINE]]) fastmath : (!fir.complex<4>) -> !fir.complex<4> ! CMPLX: return %[[RESULT32_OUTLINE]] : !fir.complex<4> -! CMPLX-FAST-LABEL: private @fir.log.contract_afn.z8.z8 +! CMPLX-APPROX-LABEL: private @fir.log.contract_afn.z8.z8 ! CMPLX-PRECISE-LABEL: private @fir.log.contract.z8.z8 +! CMPLX-MLIR-LABEL: private @fir.log.contract.z8.z8 ! CMPLX-SAME: (%[[ARG64_OUTLINE:.*]]: !fir.complex<8>) -> !fir.complex<8> ! CMPLX-FAST: %[[C:.*]] = fir.convert %[[ARG64_OUTLINE]] : (!fir.complex<8>) -> complex ! CMPLX-FAST: %[[E:.*]] = complex.log %[[C]] : complex diff --git a/flang/test/Lower/power-operator.f90 b/flang/test/Lower/power-operator.f90 --- a/flang/test/Lower/power-operator.f90 +++ b/flang/test/Lower/power-operator.f90 @@ -1,10 +1,10 @@ ! RUN: bbc -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,PRECISE" ! RUN: bbc --math-runtime=precise -emit-fir %s -o - | FileCheck %s --check-prefixes="PRECISE" -! RUN: bbc --disable-mlir-complex -emit-fir %s -o - | FileCheck %s --check-prefixes="PRECISE" +! RUN: bbc --force-mlir-complex -emit-fir %s -o - | FileCheck %s --check-prefixes="FAST" ! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,PRECISE" ! RUN: %flang_fc1 -fapprox-func -emit-fir %s -o - | FileCheck %s --check-prefixes="CHECK,FAST" ! RUN: %flang_fc1 -emit-fir -mllvm --math-runtime=precise %s -o - | FileCheck %s --check-prefixes="PRECISE" -! RUN: %flang_fc1 -emit-fir -mllvm --disable-mlir-complex %s -o - | FileCheck %s --check-prefixes="PRECISE" +! RUN: %flang_fc1 -emit-fir -mllvm --force-mlir-complex %s -o - | FileCheck %s --check-prefixes="FAST" ! Test power operation lowering diff --git a/flang/test/Lower/sqrt.f90 b/flang/test/Lower/sqrt.f90 --- a/flang/test/Lower/sqrt.f90 +++ b/flang/test/Lower/sqrt.f90 @@ -1,10 +1,10 @@ ! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX-PRECISE" ! 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: bbc --force-mlir-complex -emit-fir -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX-FAST" ! RUN: %flang_fc1 -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CHECK,CMPLX-PRECISE" ! RUN: %flang_fc1 -fapprox-func -emit-fir -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="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" +! RUN: %flang_fc1 -emit-fir -mllvm --force-mlir-complex -mllvm -outline-intrinsics %s -o - | FileCheck %s --check-prefixes="CMPLX-FAST" ! CHECK-LABEL: sqrt_testr subroutine sqrt_testr(a, b)