Skip to content

Commit

Permalink
[flang] Allow derf as alternate spelling for erf
Browse files Browse the repository at this point in the history
This patch adds derf as an alternate spelling for the erf intrinsic.
This spelling is supported by multiple other compilers and used by WRF.
  • Loading branch information
DavidTruby committed Jun 17, 2024
1 parent 457e895 commit 6c7cfbe
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 0 deletions.
3 changes: 3 additions & 0 deletions flang/lib/Evaluate/fold-real.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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" ||
Expand Down
1 change: 1 addition & 0 deletions flang/lib/Evaluate/intrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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}}},
Expand Down
5 changes: 5 additions & 0 deletions flang/lib/Optimizer/Builder/IntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>>,
Expand Down
3 changes: 3 additions & 0 deletions flang/test/Evaluate/folding02.f90
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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), &
Expand Down
80 changes: 80 additions & 0 deletions flang/test/Intrinsics/math-codegen.fir
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 6c7cfbe

Please sign in to comment.