[Flang] Lower sin, cos intrinsics
authorKiran Chandramohan <kiran.chandramohan@arm.com>
Wed, 23 Mar 2022 15:20:22 +0000 (15:20 +0000)
committerKiran Chandramohan <kiran.chandramohan@arm.com>
Wed, 23 Mar 2022 15:20:51 +0000 (15:20 +0000)
The intrinsic computes the sin, cosine values. By default they are lowered
to runtime calls to the pgmath library, for llvm lowering they are
lowered to llvm intrinsics. 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.

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: clementval

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

Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
flang/lib/Lower/IntrinsicCall.cpp
flang/test/Lower/llvm-math.f90
flang/test/Lower/trigonometric-intrinsics.f90

index 0afbb7b..fa405c2 100644 (file)
@@ -1019,6 +1019,8 @@ static constexpr RuntimeFunction llvmIntrinsics[] = {
     // ceil is used for CEILING but is different, it returns a real.
     {"ceil", "llvm.ceil.f32", genF32F32FuncType},
     {"ceil", "llvm.ceil.f64", genF64F64FuncType},
+    {"cos", "llvm.cos.f32", genF32F32FuncType},
+    {"cos", "llvm.cos.f64", genF64F64FuncType},
     {"cosh", "coshf", genF32F32FuncType},
     {"cosh", "cosh", genF64F64FuncType},
     {"exp", "llvm.exp.f32", genF32F32FuncType},
@@ -1040,6 +1042,8 @@ static constexpr RuntimeFunction llvmIntrinsics[] = {
     {"sign", "llvm.copysign.f64", genF64F64F64FuncType},
     {"sign", "llvm.copysign.f80", genF80F80F80FuncType},
     {"sign", "llvm.copysign.f128", genF128F128F128FuncType},
+    {"sin", "llvm.sin.f32", genF32F32FuncType},
+    {"sin", "llvm.sin.f64", genF64F64FuncType},
     {"sinh", "sinhf", genF32F32FuncType},
     {"sinh", "sinh", genF64F64FuncType},
     {"sqrt", "llvm.sqrt.f32", genF32F32FuncType},
index aab0b2b..f346642 100644 (file)
 ! CHECK-NEXT:  %0 = fir.call @llvm.sqrt.f64(%arg0) : (f64) -> f64
 ! CHECK-NEXT:   return %0 : f64
 ! CHECK-NEXT: }
+
+      SUBROUTINE COS_WRAPPER(IN, OUT)
+      REAL :: IN, OUT
+      OUT = COS(IN)
+      END SUBROUTINE
+
+! CHECK-LABEL: func private @fir.cos.f32.f32(%arg0: f32)
+! CHECK-NEXT:  %0 = fir.call @llvm.cos.f32(%arg0) : (f32) -> f32
+! CHECK-NEXT:   return %0 : f32
+! CHECK-NEXT: }
+
+      SUBROUTINE COSD_WRAPPER(IN, OUT)
+      REAL(KIND=8) :: IN, OUT
+      OUT = COS(IN)
+      END SUBROUTINE
+
+! CHECK-LABEL: func private @fir.cos.f64.f64(%arg0: f64)
+! CHECK-NEXT:  %0 = fir.call @llvm.cos.f64(%arg0) : (f64) -> f64
+! CHECK-NEXT:   return %0 : f64
+! CHECK-NEXT: }
+
+      SUBROUTINE SIN_WRAPPER(IN, OUT)
+      REAL :: IN, OUT
+      OUT = SIN(IN)
+      END SUBROUTINE
+
+! CHECK-LABEL: func private @fir.sin.f32.f32(%arg0: f32)
+! CHECK-NEXT:  %0 = fir.call @llvm.sin.f32(%arg0) : (f32) -> f32
+! CHECK-NEXT:   return %0 : f32
+! CHECK-NEXT: }
+
+      SUBROUTINE SIND_WRAPPER(IN, OUT)
+      REAL(KIND=8) :: IN, OUT
+      OUT = SIN(IN)
+      END SUBROUTINE
+
+! CHECK-LABEL: func private @fir.sin.f64.f64(%arg0: f64)
+! CHECK-NEXT:  %0 = fir.call @llvm.sin.f64(%arg0) : (f64) -> f64
+! CHECK-NEXT:   return %0 : f64
+! CHECK-NEXT: }
index 8ec8f13..51d6e14 100644 (file)
@@ -29,6 +29,34 @@ subroutine atan_testcd(z)
   z = atan(z)
 end subroutine
 
+! CHECK-LABEL: cos_testr
+subroutine cos_testr(a, b)
+  real :: a, b
+! CHECK: fir.call @fir.cos.f32.f32
+  b = cos(a)
+end subroutine
+
+! CHECK-LABEL: cos_testd
+subroutine cos_testd(a, b)
+  real(kind=8) :: a, b
+! CHECK: fir.call @fir.cos.f64.f64
+  b = cos(a)
+end subroutine
+
+! CHECK-LABEL: cos_testc
+subroutine cos_testc(z)
+  complex :: z
+! CHECK: fir.call @fir.cos.z4.z4
+  z = cos(z)
+end subroutine
+
+! CHECK-LABEL: cos_testcd
+subroutine cos_testcd(z)
+  complex(kind=8) :: z
+! CHECK: fir.call @fir.cos.z8.z8
+  z = cos(z)
+end subroutine
+
 ! CHECK-LABEL: cosh_testr
 subroutine cosh_testr(a, b)
   real :: a, b
@@ -57,6 +85,34 @@ subroutine cosh_testcd(z)
   z = cosh(z)
 end subroutine
 
+! CHECK-LABEL: sin_testr
+subroutine sin_testr(a, b)
+  real :: a, b
+! CHECK: fir.call @fir.sin.f32.f32
+  b = sin(a)
+end subroutine
+
+! CHECK-LABEL: sin_testd
+subroutine sin_testd(a, b)
+  real(kind=8) :: a, b
+! CHECK: fir.call @fir.sin.f64.f64
+  b = sin(a)
+end subroutine
+
+! CHECK-LABEL: sin_testc
+subroutine sin_testc(z)
+  complex :: z
+! CHECK: fir.call @fir.sin.z4.z4
+  z = sin(z)
+end subroutine
+
+! CHECK-LABEL: sin_testcd
+subroutine sin_testcd(z)
+  complex(kind=8) :: z
+! CHECK: fir.call @fir.sin.z8.z8
+  z = sin(z)
+end subroutine
+
 ! CHECK-LABEL: sinh_testr
 subroutine sinh_testr(a, b)
   real :: a, b
@@ -97,6 +153,18 @@ end subroutine
 ! CHECK-LABEL: @fir.atan.z8.z8
 ! CHECK: fir.call {{.*}}atan
 
+! CHECK-LABEL: @fir.cos.f32.f32
+! CHECK: fir.call {{.*}}cos
+
+! CHECK-LABEL: @fir.cos.f64.f64
+! CHECK: fir.call {{.*}}cos
+
+! CHECK-LABEL: @fir.cos.z4.z4
+! CHECK: fir.call {{.*}}cos
+
+! CHECK-LABEL: @fir.cos.z8.z8
+! CHECK: fir.call {{.*}}cos
+
 ! CHECK-LABEL: @fir.cosh.f32.f32
 ! CHECK: fir.call {{.*}}cosh
 
@@ -109,6 +177,18 @@ end subroutine
 ! CHECK-LABEL: @fir.cosh.z8.z8
 ! CHECK: fir.call {{.*}}cosh
 
+! CHECK-LABEL: @fir.sin.f32.f32
+! CHECK: fir.call {{.*}}sin
+
+! CHECK-LABEL: @fir.sin.f64.f64
+! CHECK: fir.call {{.*}}sin
+
+! CHECK-LABEL: @fir.sin.z4.z4
+! CHECK: fir.call {{.*}}sin
+
+! CHECK-LABEL: @fir.sin.z8.z8
+! CHECK: fir.call {{.*}}sin
+
 ! CHECK-LABEL: @fir.sinh.f32.f32
 ! CHECK: fir.call {{.*}}sinh