[flang-commits] [flang] [flang] Allow derf as alternate spelling for erf (PR #95784)

David Truby via flang-commits flang-commits at lists.llvm.org
Mon Jun 17 06:26:25 PDT 2024


https://github.com/DavidTruby created https://github.com/llvm/llvm-project/pull/95784

This patch adds derf as an alternate spelling for the erf intrinsic.
This spelling is supported by multiple other compilers and used by WRF.


>From 6c7cfbe34e7bb98cf3cb71a92ba89b580b77958d Mon Sep 17 00:00:00 2001
From: David Truby <david.truby at arm.com>
Date: Mon, 17 Jun 2024 13:24:51 +0000
Subject: [PATCH] [flang] Allow derf as alternate spelling for erf

This patch adds derf as an alternate spelling for the erf intrinsic.
This spelling is supported by multiple other compilers and used by WRF.
---
 flang/lib/Evaluate/fold-real.cpp              |  3 +
 flang/lib/Evaluate/intrinsics.cpp             |  1 +
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp |  5 ++
 flang/test/Evaluate/folding02.f90             |  3 +
 flang/test/Intrinsics/math-codegen.fir        | 80 +++++++++++++++++++
 5 files changed, 92 insertions(+)

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



More information about the flang-commits mailing list