[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