diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp index 4685ac45837bc..94c83dd3e12ee 100644 --- a/flang/lib/Lower/IntrinsicCall.cpp +++ b/flang/lib/Lower/IntrinsicCall.cpp @@ -942,11 +942,18 @@ static llvm::cl::opt outlineAllIntrinsics( /// Command line option to modify math runtime version used to implement /// intrinsics. -enum MathRuntimeVersion { fastVersion, llvmOnly }; +enum MathRuntimeVersion { + fastVersion, + relaxedVersion, + preciseVersion, + llvmOnly +}; llvm::cl::opt mathRuntimeVersion( "math-runtime", llvm::cl::desc("Select math runtime version:"), llvm::cl::values( clEnumValN(fastVersion, "fast", "use pgmath fast runtime"), + clEnumValN(relaxedVersion, "relaxed", "use pgmath relaxed runtime"), + clEnumValN(preciseVersion, "precise", "use pgmath precise runtime"), clEnumValN(llvmOnly, "llvm", "only use LLVM intrinsics (may be incomplete)")), llvm::cl::init(fastVersion)); @@ -968,6 +975,16 @@ static constexpr RuntimeFunction pgmathFast[] = { #define PGMATH_USE_ALL_TYPES(name, func) RUNTIME_STATIC_DESCRIPTION(name, func) #include "flang/Evaluate/pgmath.h.inc" }; +static constexpr RuntimeFunction pgmathRelaxed[] = { +#define PGMATH_RELAXED +#define PGMATH_USE_ALL_TYPES(name, func) RUNTIME_STATIC_DESCRIPTION(name, func) +#include "flang/Evaluate/pgmath.h.inc" +}; +static constexpr RuntimeFunction pgmathPrecise[] = { +#define PGMATH_PRECISE +#define PGMATH_USE_ALL_TYPES(name, func) RUNTIME_STATIC_DESCRIPTION(name, func) +#include "flang/Evaluate/pgmath.h.inc" +}; static mlir::FunctionType genF32F32FuncType(mlir::MLIRContext *context) { mlir::Type t = mlir::FloatType::getF32(context); @@ -1250,9 +1267,19 @@ static mlir::FuncOp getRuntimeFunction(mlir::Location loc, using RtMap = Fortran::common::StaticMultimapView; static constexpr RtMap pgmathF(pgmathFast); static_assert(pgmathF.Verify() && "map must be sorted"); + static constexpr RtMap pgmathR(pgmathRelaxed); + static_assert(pgmathR.Verify() && "map must be sorted"); + static constexpr RtMap pgmathP(pgmathPrecise); + static_assert(pgmathP.Verify() && "map must be sorted"); if (mathRuntimeVersion == fastVersion) { match = searchFunctionInLibrary(loc, builder, pgmathF, name, funcType, &bestNearMatch, bestMatchDistance); + } else if (mathRuntimeVersion == relaxedVersion) { + match = searchFunctionInLibrary(loc, builder, pgmathR, name, funcType, + &bestNearMatch, bestMatchDistance); + } else if (mathRuntimeVersion == preciseVersion) { + match = searchFunctionInLibrary(loc, builder, pgmathP, name, funcType, + &bestNearMatch, bestMatchDistance); } else { assert(mathRuntimeVersion == llvmOnly && "unknown math runtime"); } diff --git a/flang/test/Lower/Intrinsics/math-runtime-options.f90 b/flang/test/Lower/Intrinsics/math-runtime-options.f90 new file mode 100644 index 0000000000000..f2439cef14ed0 --- /dev/null +++ b/flang/test/Lower/Intrinsics/math-runtime-options.f90 @@ -0,0 +1,29 @@ +! RUN: bbc -emit-fir --math-runtime=fast %s -o - | FileCheck %s --check-prefixes="FIR,FAST" +! RUN: bbc -emit-fir --math-runtime=relaxed %s -o - | FileCheck %s --check-prefixes="FIR,RELAXED" +! RUN: bbc -emit-fir --math-runtime=precise %s -o - | FileCheck %s --check-prefixes="FIR,PRECISE" +! RUN: bbc -emit-fir --math-runtime=llvm %s -o - | FileCheck %s --check-prefixes="FIR,LLVM" + +! CHECK-LABEL: cos_testr +subroutine cos_testr(a, b) + real :: a, b +! FIR: fir.call @fir.cos.f32.f32 + b = cos(a) +end subroutine + +! CHECK-LABEL: cos_testd +subroutine cos_testd(a, b) + real(kind=8) :: a, b +! FIR: fir.call @fir.cos.f64.f64 + b = cos(a) +end subroutine + +! FIR: @fir.cos.f32.f32(%arg0: f32) -> f32 attributes +! FAST: fir.call @__fs_cos_1(%arg0) : (f32) -> f32 +! RELAXED: fir.call @__rs_cos_1(%arg0) : (f32) -> f32 +! PRECISE: fir.call @__ps_cos_1(%arg0) : (f32) -> f32 +! LLVM: fir.call @llvm.cos.f32(%arg0) : (f32) -> f32 +! FIR: @fir.cos.f64.f64(%arg0: f64) -> f64 +! FAST: fir.call @__fd_cos_1(%arg0) : (f64) -> f64 +! RELAXED: fir.call @__rd_cos_1(%arg0) : (f64) -> f64 +! PRECISE: fir.call @__pd_cos_1(%arg0) : (f64) -> f64 +! LLVM: fir.call @llvm.cos.f64(%arg0) : (f64) -> f64