-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[flang] Allow derf as alternate spelling for erf #95784
Conversation
@llvm/pr-subscribers-flang-semantics @llvm/pr-subscribers-flang-fir-hlfir Author: David Truby (DavidTruby) ChangesThis patch adds derf as an alternate spelling for the erf intrinsic. Full diff: https://github.com/llvm/llvm-project/pull/95784.diff 5 Files Affected:
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
|
DERF is mentioned as a specific name extension of ERF for argument and return type Real(kind=8). Is the usage in wrf and other codes you saw an alias of ERF for all Real kinds or specifically for Real(kind=8)? |
NB, it must match the type of other
|
Fortran extension intrinsic functions that start with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is basically all wrong.
This patch adds derf as an alternate spelling for the erf intrinsic. This spelling is supported by multiple other compilers and used by WRF.
I've reimplemented this using specificIntrinsicFunction |
This patch adds derf as an alternate spelling for the erf intrinsic. This spelling is supported by multiple other compilers and used by WRF.
This patch adds derf as an alternate spelling for the erf intrinsic.
This spelling is supported by multiple other compilers and used by WRF.