[flang-commits] [flang] 3d94851 - [Flang] Lower atan, sinh, cosh intrinsics

Kiran Chandramohan via flang-commits flang-commits at lists.llvm.org
Wed Mar 23 07:47:14 PDT 2022


Author: Kiran Chandramohan
Date: 2022-03-23T14:46:41Z
New Revision: 3d9485173556c4e52426bc18239c2fb423d43ac3

URL: https://github.com/llvm/llvm-project/commit/3d9485173556c4e52426bc18239c2fb423d43ac3
DIFF: https://github.com/llvm/llvm-project/commit/3d9485173556c4e52426bc18239c2fb423d43ac3.diff

LOG: [Flang] Lower atan, sinh, cosh intrinsics

The intrinsic computes the tan and hyperbolic sin, cosine values. By
default they are lowered to runtime calls to the math library. Not all
types are supported currently. The generic and llvm lowering does not
lower floating point types with kind greater than 8, the llvm lowering
does not support the complex types.

Note: tanh is not present in fir-dev hence ignoring for now. We can add
support after upstreaming is complete. sin and cos will come in separate
patches since they have llvm intrinsic lowering.

This is part of the upstreaming effort from the fir-dev branch in [1].
[1] https://github.com/flang-compiler/f18-llvm-project

Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D122264

Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>
Co-authored-by: William Moses <gh at wsmoses.com>

Added: 
    flang/test/Lower/trigonometric-intrinsics.f90

Modified: 
    flang/lib/Lower/IntrinsicCall.cpp
    flang/test/Lower/llvm-math.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp
index d364453387f17..0afbb7b1c6fa1 100644
--- a/flang/lib/Lower/IntrinsicCall.cpp
+++ b/flang/lib/Lower/IntrinsicCall.cpp
@@ -1014,9 +1014,13 @@ static constexpr RuntimeFunction llvmIntrinsics[] = {
     {"aint", "llvm.trunc.f64", genF64F64FuncType},
     {"anint", "llvm.round.f32", genF32F32FuncType},
     {"anint", "llvm.round.f64", genF64F64FuncType},
+    {"atan", "atanf", genF32F32FuncType},
+    {"atan", "atan", genF64F64FuncType},
     // ceil is used for CEILING but is 
diff erent, it returns a real.
     {"ceil", "llvm.ceil.f32", genF32F32FuncType},
     {"ceil", "llvm.ceil.f64", genF64F64FuncType},
+    {"cosh", "coshf", genF32F32FuncType},
+    {"cosh", "cosh", genF64F64FuncType},
     {"exp", "llvm.exp.f32", genF32F32FuncType},
     {"exp", "llvm.exp.f64", genF64F64FuncType},
     // llvm.floor is used for FLOOR, but returns real.
@@ -1036,6 +1040,8 @@ static constexpr RuntimeFunction llvmIntrinsics[] = {
     {"sign", "llvm.copysign.f64", genF64F64F64FuncType},
     {"sign", "llvm.copysign.f80", genF80F80F80FuncType},
     {"sign", "llvm.copysign.f128", genF128F128F128FuncType},
+    {"sinh", "sinhf", genF32F32FuncType},
+    {"sinh", "sinh", genF64F64FuncType},
     {"sqrt", "llvm.sqrt.f32", genF32F32FuncType},
     {"sqrt", "llvm.sqrt.f64", genF64F64FuncType},
 };

diff  --git a/flang/test/Lower/llvm-math.f90 b/flang/test/Lower/llvm-math.f90
index efe4394804c0e..aab0b2b1f079d 100644
--- a/flang/test/Lower/llvm-math.f90
+++ b/flang/test/Lower/llvm-math.f90
@@ -24,6 +24,17 @@ SUBROUTINE POWF_WRAPPER(IN, IN2, OUT)
 ! CHECK-NEXT:   %1 = fir.load %arg1 : !fir.ref<f32>
 ! CHECK-NEXT:   %2 = fir.call @llvm.pow.f32(%0, %1) : (f32, f32) -> f32
 
+      SUBROUTINE ATAN_WRAPPER(IN, OUT)
+      DOUBLE PRECISION IN
+      OUT = DATAN(IN)
+      RETURN
+      END
+
+! CHECK:       func private @fir.atan.f64.f64(%arg0: f64)
+! CHECK-NEXT:   %0 = fir.call @atan(%arg0) : (f64) -> f64
+! CHECK-NEXT:   return %0 : f64
+! CHECK-NEXT: }
+
       SUBROUTINE EXP_WRAPPER(IN, OUT)
       DOUBLE PRECISION IN
       OUT = DEXP(IN)
@@ -35,28 +46,40 @@ SUBROUTINE EXP_WRAPPER(IN, OUT)
 ! CHECK-NEXT:   return %0 : f64
 ! CHECK-NEXT: }
 
-      SUBROUTINE LOG_WRAPPER(IN, OUT)
-      DOUBLE PRECISION IN, OUT
-      OUT = DLOG(IN)
+      SUBROUTINE SINH_WRAPPER(IN, OUT)
+      DOUBLE PRECISION IN
+      OUT = DSINH(IN)
       RETURN
       END
 
-! CHECK:       func private @fir.log.f64.f64(%arg0: f64)
-! CHECK-NEXT:   %0 = fir.call @llvm.log.f64(%arg0) : (f64) -> f64
+! CHECK:       func private @fir.sinh.f64.f64(%arg0: f64)
+! CHECK-NEXT:   %0 = fir.call @sinh(%arg0) : (f64) -> f64
 ! CHECK-NEXT:   return %0 : f64
 ! CHECK-NEXT: }
 
-      SUBROUTINE LOG10_WRAPPER(IN, OUT)
-      DOUBLE PRECISION IN, OUT
-      OUT = DLOG10(IN)
+      SUBROUTINE COSH_WRAPPER(IN, OUT)
+      DOUBLE PRECISION IN
+      OUT = DCOSH(IN)
       RETURN
       END
 
-! CHECK:       func private @fir.log10.f64.f64(%arg0: f64)
-! CHECK-NEXT:   %0 = fir.call @llvm.log10.f64(%arg0) : (f64) -> f64
+! CHECK:       func private @fir.cosh.f64.f64(%arg0: f64)
+! CHECK-NEXT:   %0 = fir.call @cosh(%arg0) : (f64) -> f64
 ! CHECK-NEXT:   return %0 : f64
 ! CHECK-NEXT: }
 
+
+      SUBROUTINE ATANF_WRAPPER(IN, OUT)
+      REAL IN
+      OUT = ATAN(IN)
+      RETURN
+      END
+
+! CHECK:       func private @fir.atan.f32.f32(%arg0: f32)
+! CHECK-NEXT:   %0 = fir.call @atanf(%arg0) : (f32) -> f32
+! CHECK-NEXT:   return %0 : f32
+! CHECK-NEXT: }
+
       SUBROUTINE EXPF_WRAPPER(IN, OUT)
       REAL IN
       OUT = EXP(IN)
@@ -66,6 +89,50 @@ SUBROUTINE EXPF_WRAPPER(IN, OUT)
 ! CHECK:       func private @fir.exp.f32.f32(%arg0: f32)
 ! CHECK-NEXT:   %0 = fir.call @llvm.exp.f32(%arg0) : (f32) -> f32
 ! CHECK-NEXT:   return %0 : f32
+! CHECK-NEXT: }
+
+      SUBROUTINE SINHF_WRAPPER(IN, OUT)
+      REAL IN
+      OUT = SINH(IN)
+      RETURN
+      END
+
+! CHECK:       func private @fir.sinh.f32.f32(%arg0: f32)
+! CHECK-NEXT:   %0 = fir.call @sinhf(%arg0) : (f32) -> f32
+! CHECK-NEXT:   return %0 : f32
+! CHECK-NEXT: }
+
+      SUBROUTINE COSHF_WRAPPER(IN, OUT)
+      REAL IN
+      OUT = COSH(IN)
+      RETURN
+      END
+
+! CHECK:       func private @fir.cosh.f32.f32(%arg0: f32)
+! CHECK-NEXT:   %0 = fir.call @coshf(%arg0) : (f32) -> f32
+! CHECK-NEXT:   return %0 : f32
+! CHECK-NEXT: }
+
+      SUBROUTINE LOG_WRAPPER(IN, OUT)
+      DOUBLE PRECISION IN, OUT
+      OUT = DLOG(IN)
+      RETURN
+      END
+
+! CHECK:       func private @fir.log.f64.f64(%arg0: f64)
+! CHECK-NEXT:   %0 = fir.call @llvm.log.f64(%arg0) : (f64) -> f64
+! CHECK-NEXT:   return %0 : f64
+! CHECK-NEXT: }
+
+      SUBROUTINE LOG10_WRAPPER(IN, OUT)
+      DOUBLE PRECISION IN, OUT
+      OUT = DLOG10(IN)
+      RETURN
+      END
+
+! CHECK:       func private @fir.log10.f64.f64(%arg0: f64)
+! CHECK-NEXT:   %0 = fir.call @llvm.log10.f64(%arg0) : (f64) -> f64
+! CHECK-NEXT:   return %0 : f64
 ! CHECK-NEXT: }
 
       SUBROUTINE LOGF_WRAPPER(IN, OUT)

diff  --git a/flang/test/Lower/trigonometric-intrinsics.f90 b/flang/test/Lower/trigonometric-intrinsics.f90
new file mode 100644
index 0000000000000..8ec8f135cb7d8
--- /dev/null
+++ b/flang/test/Lower/trigonometric-intrinsics.f90
@@ -0,0 +1,122 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: atan_testr
+subroutine atan_testr(a, b)
+  real :: a, b
+! CHECK: fir.call @fir.atan.f32.f32
+  b = atan(a)
+end subroutine
+
+! CHECK-LABEL: atan_testd
+subroutine atan_testd(a, b)
+  real(kind=8) :: a, b
+! CHECK: fir.call @fir.atan.f64.f64
+  b = atan(a)
+end subroutine
+
+! CHECK-LABEL: atan_testc
+subroutine atan_testc(z)
+  complex :: z
+! CHECK: fir.call @fir.atan.z4.z4
+  z = atan(z)
+end subroutine
+
+! CHECK-LABEL: atan_testcd
+subroutine atan_testcd(z)
+  complex(kind=8) :: z
+! CHECK: fir.call @fir.atan.z8.z8
+  z = atan(z)
+end subroutine
+
+! CHECK-LABEL: cosh_testr
+subroutine cosh_testr(a, b)
+  real :: a, b
+! CHECK: fir.call @fir.cosh.f32.f32
+  b = cosh(a)
+end subroutine
+
+! CHECK-LABEL: cosh_testd
+subroutine cosh_testd(a, b)
+  real(kind=8) :: a, b
+! CHECK: fir.call @fir.cosh.f64.f64
+  b = cosh(a)
+end subroutine
+
+! CHECK-LABEL: cosh_testc
+subroutine cosh_testc(z)
+  complex :: z
+! CHECK: fir.call @fir.cosh.z4.z4
+  z = cosh(z)
+end subroutine
+
+! CHECK-LABEL: cosh_testcd
+subroutine cosh_testcd(z)
+  complex(kind=8) :: z
+! CHECK: fir.call @fir.cosh.z8.z8
+  z = cosh(z)
+end subroutine
+
+! CHECK-LABEL: sinh_testr
+subroutine sinh_testr(a, b)
+  real :: a, b
+! CHECK: fir.call @fir.sinh.f32.f32
+  b = sinh(a)
+end subroutine
+
+! CHECK-LABEL: sinh_testd
+subroutine sinh_testd(a, b)
+  real(kind=8) :: a, b
+! CHECK: fir.call @fir.sinh.f64.f64
+  b = sinh(a)
+end subroutine
+
+! CHECK-LABEL: sinh_testc
+subroutine sinh_testc(z)
+  complex :: z
+! CHECK: fir.call @fir.sinh.z4.z4
+  z = sinh(z)
+end subroutine
+
+! CHECK-LABEL: sinh_testcd
+subroutine sinh_testcd(z)
+  complex(kind=8) :: z
+! CHECK: fir.call @fir.sinh.z8.z8
+  z = sinh(z)
+end subroutine
+
+! CHECK-LABEL: @fir.atan.f32.f32
+! CHECK: fir.call {{.*}}atan
+
+! CHECK-LABEL: @fir.atan.f64.f64
+! CHECK: fir.call {{.*}}atan
+
+! CHECK-LABEL: @fir.atan.z4.z4
+! CHECK: fir.call {{.*}}atan
+
+! CHECK-LABEL: @fir.atan.z8.z8
+! CHECK: fir.call {{.*}}atan
+
+! CHECK-LABEL: @fir.cosh.f32.f32
+! CHECK: fir.call {{.*}}cosh
+
+! CHECK-LABEL: @fir.cosh.f64.f64
+! CHECK: fir.call {{.*}}cosh
+
+! CHECK-LABEL: @fir.cosh.z4.z4
+! CHECK: fir.call {{.*}}cosh
+
+! CHECK-LABEL: @fir.cosh.z8.z8
+! CHECK: fir.call {{.*}}cosh
+
+! CHECK-LABEL: @fir.sinh.f32.f32
+! CHECK: fir.call {{.*}}sinh
+
+! CHECK-LABEL: @fir.sinh.f64.f64
+! CHECK: fir.call {{.*}}sinh
+
+! CHECK-LABEL: @fir.sinh.z4.z4
+! CHECK: fir.call {{.*}}sinh
+
+! CHECK-LABEL: @fir.sinh.z8.z8
+! CHECK: fir.call {{.*}}sinh


        


More information about the flang-commits mailing list