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 different, 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 ! 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