[flang-commits] [flang] [flang] Allow derf as alternate spelling for erf (PR #95784)
via flang-commits
flang-commits at lists.llvm.org
Mon Jun 17 06:26:53 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: David Truby (DavidTruby)
<details>
<summary>Changes</summary>
This patch adds derf as an alternate spelling for the erf intrinsic.
This spelling is supported by multiple other compilers and used by WRF.
---
Full diff: https://github.com/llvm/llvm-project/pull/95784.diff
5 Files Affected:
- (modified) flang/lib/Evaluate/fold-real.cpp (+3)
- (modified) flang/lib/Evaluate/intrinsics.cpp (+1)
- (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+5)
- (modified) flang/test/Evaluate/folding02.f90 (+3)
- (modified) flang/test/Intrinsics/math-codegen.fir (+80)
``````````diff
diff --git a/flang/lib/Evaluate/fold-real.cpp b/flang/lib/Evaluate/fold-real.cpp
index f71addcc4094a..d951197b8eb6c 100644
--- a/flang/lib/Evaluate/fold-real.cpp
+++ b/flang/lib/Evaluate/fold-real.cpp
@@ -153,6 +153,9 @@ Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction(
auto *intrinsic{std::get_if<SpecificIntrinsic>(&funcRef.proc().u)};
CHECK(intrinsic);
std::string name{intrinsic->name};
+ if (name == "derf") {
+ name = "erf";
+ }
if (name == "acos" || name == "acosh" || name == "asin" || name == "asinh" ||
(name == "atan" && args.size() == 1) || name == "atanh" ||
name == "bessel_j0" || name == "bessel_j1" || name == "bessel_y0" ||
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index ace316174a892..212134b75c97d 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -403,6 +403,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
{"shift", AnyInt, Rank::dimRemovedOrScalar}, OptionalDIM},
SameType, Rank::conformable, IntrinsicClass::transformationalFunction},
{"dble", {{"a", AnyNumeric, Rank::elementalOrBOZ}}, DoublePrecision},
+ {"derf", {{"x", SameReal}}, SameReal},
{"digits",
{{"x", AnyIntOrReal, Rank::anyOrAssumedRank, Optionality::required,
common::Intent::In, {ArgFlag::canBeMoldNull}}},
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index ab106f62aecfb..beb9011ee5fe6 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -1101,6 +1101,11 @@ static constexpr MathOperation mathOperations[] = {
{"cosh", "ccosh", genFuncType<Ty::Complex<8>, Ty::Complex<8>>, genLibCall},
{"cosh", RTNAME_STRING(CCoshF128), FuncTypeComplex16Complex16,
genLibF128Call},
+ {"derf", "derff", genFuncType<Ty::Real<4>, Ty::Real<4>>,
+ genMathOp<mlir::math::ErfOp>},
+ {"derf", "derf", genFuncType<Ty::Real<8>, Ty::Real<8>>,
+ genMathOp<mlir::math::ErfOp>},
+ {"derf", RTNAME_STRING(ErfF128), FuncTypeReal16Real16, genLibF128Call},
{"divc",
{},
genFuncType<Ty::Complex<2>, Ty::Complex<2>, Ty::Complex<2>>,
diff --git a/flang/test/Evaluate/folding02.f90 b/flang/test/Evaluate/folding02.f90
index 89e2a09aa31b7..4581b3cf8ea5b 100644
--- a/flang/test/Evaluate/folding02.f90
+++ b/flang/test/Evaluate/folding02.f90
@@ -57,6 +57,7 @@ module m
TEST_R4(atanh, atanh(0.8_4), 1.098612308502197265625_4)
TEST_R4(cos, cos(0.5_4), 0.877582550048828125_4)
TEST_R4(cosh, cosh(0.1_4), 1.0050041675567626953125_4)
+ TEST_R4(derf, derf(1._4), 0.842700779438018798828125_4)
TEST_R4(erf, erf(1._4), 0.842700779438018798828125_4)
TEST_R4(erfc, erfc(0.1_4), 0.887537062168121337890625_4)
TEST_R4(exp, exp(0.1_4), 1.1051709651947021484375_4)
@@ -97,6 +98,8 @@ module m
0.8775825618903727587394314468838274478912353515625_8)
TEST_R8(cosh, cosh(0.1_8), &
1.0050041680558035039894093642942607402801513671875_8)
+ TEST_R8(derf, derf(1._8), &
+ 0.84270079294971489414223242420121096074581146240234375_8)
TEST_R8(erf, erf(1._8), &
0.84270079294971489414223242420121096074581146240234375_8)
TEST_R8(erfc, erfc(0.1_8), &
diff --git a/flang/test/Intrinsics/math-codegen.fir b/flang/test/Intrinsics/math-codegen.fir
index 62d841253075e..4555e33fead20 100644
--- a/flang/test/Intrinsics/math-codegen.fir
+++ b/flang/test/Intrinsics/math-codegen.fir
@@ -862,6 +862,86 @@ func.func @_QPtest_real8(%arg0: !fir.ref<f64> {fir.bindc_name = "x"}) -> f64 {
func.func private @erff(f32) -> f32
func.func private @erf(f64) -> f64
+
+//--- derf_fast.fir
+// RUN: fir-opt %t/derf_fast.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/derf_fast.fir
+// CHECK: @_QPtest_real4
+// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @erff({{%[A-Za-z0-9._]+}}) : (f32) -> f32
+
+// CHECK: @_QPtest_real8
+// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @erf({{%[A-Za-z0-9._]+}}) : (f64) -> f64
+
+func.func @_QPtest_real4(%arg0: !fir.ref<f32> {fir.bindc_name = "x"}) -> f32 {
+ %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"}
+ %1 = fir.load %arg0 : !fir.ref<f32>
+ %2 = math.erf %1 : f32
+ fir.store %2 to %0 : !fir.ref<f32>
+ %3 = fir.load %0 : !fir.ref<f32>
+ return %3 : f32
+}
+func.func @_QPtest_real8(%arg0: !fir.ref<f64> {fir.bindc_name = "x"}) -> f64 {
+ %0 = fir.alloca f64 {bindc_name = "test_real8", uniq_name = "_QFtest_real8Etest_real8"}
+ %1 = fir.load %arg0 : !fir.ref<f64>
+ %2 = math.erf %1 : f64
+ fir.store %2 to %0 : !fir.ref<f64>
+ %3 = fir.load %0 : !fir.ref<f64>
+ return %3 : f64
+}
+
+//--- derf_relaxed.fir
+// RUN: fir-opt %t/derf_relaxed.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/derf_relaxed.fir
+// CHECK: @_QPtest_real4
+// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @erff({{%[A-Za-z0-9._]+}}) : (f32) -> f32
+
+// CHECK: @_QPtest_real8
+// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @erf({{%[A-Za-z0-9._]+}}) : (f64) -> f64
+
+func.func @_QPtest_real4(%arg0: !fir.ref<f32> {fir.bindc_name = "x"}) -> f32 {
+ %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"}
+ %1 = fir.load %arg0 : !fir.ref<f32>
+ %2 = math.erf %1 : f32
+ fir.store %2 to %0 : !fir.ref<f32>
+ %3 = fir.load %0 : !fir.ref<f32>
+ return %3 : f32
+}
+func.func @_QPtest_real8(%arg0: !fir.ref<f64> {fir.bindc_name = "x"}) -> f64 {
+ %0 = fir.alloca f64 {bindc_name = "test_real8", uniq_name = "_QFtest_real8Etest_real8"}
+ %1 = fir.load %arg0 : !fir.ref<f64>
+ %2 = math.erf %1 : f64
+ fir.store %2 to %0 : !fir.ref<f64>
+ %3 = fir.load %0 : !fir.ref<f64>
+ return %3 : f64
+}
+
+//--- derf_precise.fir
+// RUN: fir-opt %t/derf_precise.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/derf_precise.fir
+// CHECK: @_QPtest_real4
+// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @erff({{%[A-Za-z0-9._]+}}) : (f32) -> f32
+
+// CHECK: @_QPtest_real8
+// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @erf({{%[A-Za-z0-9._]+}}) : (f64) -> f64
+
+func.func @_QPtest_real4(%arg0: !fir.ref<f32> {fir.bindc_name = "x"}) -> f32 {
+ %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"}
+ %1 = fir.load %arg0 : !fir.ref<f32>
+ %2 = fir.call @erff(%1) : (f32) -> f32
+ fir.store %2 to %0 : !fir.ref<f32>
+ %3 = fir.load %0 : !fir.ref<f32>
+ return %3 : f32
+}
+func.func @_QPtest_real8(%arg0: !fir.ref<f64> {fir.bindc_name = "x"}) -> f64 {
+ %0 = fir.alloca f64 {bindc_name = "test_real8", uniq_name = "_QFtest_real8Etest_real8"}
+ %1 = fir.load %arg0 : !fir.ref<f64>
+ %2 = fir.call @erf(%1) : (f64) -> f64
+ fir.store %2 to %0 : !fir.ref<f64>
+ %3 = fir.load %0 : !fir.ref<f64>
+ return %3 : f64
+}
+func.func private @erff(f32) -> f32
+func.func private @erf(f64) -> f64
+
+
+
//--- exp_fast.fir
// RUN: fir-opt %t/exp_fast.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/exp_fast.fir
// CHECK: @_QPtest_real4
``````````
</details>
https://github.com/llvm/llvm-project/pull/95784
More information about the flang-commits
mailing list