diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp --- a/flang/lib/Lower/IntrinsicCall.cpp +++ b/flang/lib/Lower/IntrinsicCall.cpp @@ -1044,6 +1044,11 @@ return mlir::FunctionType::get(context, {t}, {t}); } +static mlir::FunctionType genF128F128FuncType(mlir::MLIRContext *context) { + mlir::Type t = mlir::FloatType::getF128(context); + return mlir::FunctionType::get(context, {t}, {t}); +} + static mlir::FunctionType genF32F32F32FuncType(mlir::MLIRContext *context) { auto t = mlir::FloatType::getF32(context); return mlir::FunctionType::get(context, {t, t}, {t}); @@ -1179,6 +1184,8 @@ static constexpr MathOperation mathOperations[] = { {"abs", "fabsf", genF32F32FuncType, genMathOp}, {"abs", "fabs", genF64F64FuncType, genMathOp}, + {"abs", "llvm.fabs.f128", genF128F128FuncType, + genMathOp}, // llvm.trunc behaves the same way as libm's trunc. {"aint", "llvm.trunc.f32", genF32F32FuncType, genLibCall}, {"aint", "llvm.trunc.f64", genF64F64FuncType, genLibCall}, @@ -1196,6 +1203,8 @@ {"ceil", "ceil", genF64F64FuncType, genMathOp}, {"cos", "cosf", genF32F32FuncType, genMathOp}, {"cos", "cos", genF64F64FuncType, genMathOp}, + {"cosh", "coshf", genF32F32FuncType, genLibCall}, + {"cosh", "cosh", genF64F64FuncType, genLibCall}, {"erf", "erff", genF32F32FuncType, genMathOp}, {"erf", "erf", genF64F64FuncType, genMathOp}, {"exp", "expf", genF32F32FuncType, genMathOp}, @@ -1223,10 +1232,18 @@ genMathOp}, {"sign", "copysign", genF64F64F64FuncType, genMathOp}, + {"sign", "copysignl", genF80F80F80FuncType, + genMathOp}, + {"sign", "llvm.copysign.f128", genF128F128F128FuncType, + genMathOp}, {"sin", "sinf", genF32F32FuncType, genMathOp}, {"sin", "sin", genF64F64FuncType, genMathOp}, + {"sinh", "sinhf", genF32F32FuncType, genLibCall}, + {"sinh", "sinh", genF64F64FuncType, genLibCall}, {"sqrt", "sqrtf", genF32F32FuncType, genMathOp}, {"sqrt", "sqrt", genF64F64FuncType, genMathOp}, + {"tan", "tanf", genF32F32FuncType, genMathOp}, + {"tan", "tan", genF64F64FuncType, genMathOp}, {"tanh", "tanhf", genF32F32FuncType, genMathOp}, {"tanh", "tanh", genF64F64FuncType, genMathOp}, }; @@ -1243,6 +1260,7 @@ static constexpr RuntimeFunction llvmIntrinsics[] = { {"abs", "llvm.fabs.f32", genF32F32FuncType}, {"abs", "llvm.fabs.f64", genF64F64FuncType}, + {"abs", "llvm.fabs.f128", genF128F128FuncType}, {"aint", "llvm.trunc.f32", genF32F32FuncType}, {"aint", "llvm.trunc.f64", genF64F64FuncType}, {"anint", "llvm.round.f32", genF32F32FuncType}, diff --git a/flang/test/Intrinsics/late-math-codegen.fir b/flang/test/Intrinsics/late-math-codegen.fir --- a/flang/test/Intrinsics/late-math-codegen.fir +++ b/flang/test/Intrinsics/late-math-codegen.fir @@ -9,6 +9,9 @@ // CHECK: @_QPtest_real8 // CHECK: {{%[A-Za-z0-9._]+}} = "llvm.intr.fabs"({{%[A-Za-z0-9._]+}}) : (f64) -> f64 +// CHECK: @_QPtest_real16 +// CHECK: {{%[A-Za-z0-9._]+}} = "llvm.intr.fabs"({{%[A-Za-z0-9._]+}}) : (f128) -> f128 + // CHECK: @_QPtest_complex4 // CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @hypotf({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f32, f32) -> f32 @@ -31,6 +34,14 @@ %3 = fir.load %0 : !fir.ref return %3 : f64 } +func.func @_QPtest_real16(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f128 { + %0 = fir.alloca f128 {bindc_name = "test_real16", uniq_name = "_QFtest_real16Etest_real16"} + %1 = fir.load %arg0 : !fir.ref + %2 = math.abs %1 : f128 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f128 +} func.func @_QPtest_complex4(%arg0: !fir.ref> {fir.bindc_name = "c"}) -> !fir.complex<4> { %0 = fir.alloca !fir.complex<4> {bindc_name = "test_complex4", uniq_name = "_QFtest_complex4Etest_complex4"} %1 = fir.load %arg0 : !fir.ref> @@ -70,6 +81,9 @@ // CHECK: @_QPtest_real8 // CHECK: {{%[A-Za-z0-9._]+}} = "llvm.intr.fabs"({{%[A-Za-z0-9._]+}}) : (f64) -> f64 +// CHECK: @_QPtest_real16 +// CHECK: {{%[A-Za-z0-9._]+}} = "llvm.intr.fabs"({{%[A-Za-z0-9._]+}}) : (f128) -> f128 + // CHECK: @_QPtest_complex4 // CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @hypotf({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f32, f32) -> f32 @@ -92,6 +106,14 @@ %3 = fir.load %0 : !fir.ref return %3 : f64 } +func.func @_QPtest_real16(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f128 { + %0 = fir.alloca f128 {bindc_name = "test_real16", uniq_name = "_QFtest_real16Etest_real16"} + %1 = fir.load %arg0 : !fir.ref + %2 = math.abs %1 : f128 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f128 +} func.func @_QPtest_complex4(%arg0: !fir.ref> {fir.bindc_name = "c"}) -> !fir.complex<4> { %0 = fir.alloca !fir.complex<4> {bindc_name = "test_complex4", uniq_name = "_QFtest_complex4Etest_complex4"} %1 = fir.load %arg0 : !fir.ref> @@ -131,6 +153,9 @@ // CHECK: @_QPtest_real8 // CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @fabs({{%[A-Za-z0-9._]+}}) : (f64) -> f64 +// CHECK: @_QPtest_real16 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @llvm.fabs.f128({{%[A-Za-z0-9._]+}}) : (f128) -> f128 + // CHECK: @_QPtest_complex4 // CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @hypotf({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f32, f32) -> f32 @@ -153,6 +178,14 @@ %3 = fir.load %0 : !fir.ref return %3 : f64 } +func.func @_QPtest_real16(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f128 { + %0 = fir.alloca f128 {bindc_name = "test_real16", uniq_name = "_QFtest_real16Etest_real16"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @llvm.fabs.f128(%1) : (f128) -> f128 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f128 +} func.func @_QPtest_complex4(%arg0: !fir.ref> {fir.bindc_name = "c"}) -> !fir.complex<4> { %0 = fir.alloca !fir.complex<4> {bindc_name = "test_complex4", uniq_name = "_QFtest_complex4Etest_complex4"} %1 = fir.load %arg0 : !fir.ref> @@ -183,6 +216,7 @@ } func.func private @fabsf(f32) -> f32 func.func private @fabs(f64) -> f64 +func.func private @llvm.fabs.f128(f128) -> f128 func.func private @hypotf(f32, f32) -> f32 func.func private @hypot(f64, f64) -> f64 @@ -670,6 +704,87 @@ func.func private @cosf(f32) -> f32 func.func private @cos(f64) -> f64 +//--- cosh_fast.fir +// RUN: fir-opt %t/cosh_fast.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/cosh_fast.fir +// CHECK: @_QPtest_real4 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @coshf({{%[A-Za-z0-9._]+}}) : (f32) -> f32 + +// CHECK: @_QPtest_real8 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @cosh({{%[A-Za-z0-9._]+}}) : (f64) -> f64 + +func.func @_QPtest_real4(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f32 { + %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @coshf(%1) : (f32) -> f32 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f32 +} +func.func @_QPtest_real8(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f64 { + %0 = fir.alloca f64 {bindc_name = "test_real8", uniq_name = "_QFtest_real8Etest_real8"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @cosh(%1) : (f64) -> f64 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f64 +} +func.func private @coshf(f32) -> f32 +func.func private @cosh(f64) -> f64 + +//--- cosh_relaxed.fir +// RUN: fir-opt %t/cosh_relaxed.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/cosh_relaxed.fir +// CHECK: @_QPtest_real4 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @coshf({{%[A-Za-z0-9._]+}}) : (f32) -> f32 + +// CHECK: @_QPtest_real8 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @cosh({{%[A-Za-z0-9._]+}}) : (f64) -> f64 + +func.func @_QPtest_real4(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f32 { + %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @coshf(%1) : (f32) -> f32 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f32 +} +func.func @_QPtest_real8(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f64 { + %0 = fir.alloca f64 {bindc_name = "test_real8", uniq_name = "_QFtest_real8Etest_real8"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @cosh(%1) : (f64) -> f64 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f64 +} +func.func private @coshf(f32) -> f32 +func.func private @cosh(f64) -> f64 + +//--- cosh_precise.fir +// RUN: fir-opt %t/cosh_precise.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/cosh_precise.fir +// CHECK: @_QPtest_real4 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @coshf({{%[A-Za-z0-9._]+}}) : (f32) -> f32 + +// CHECK: @_QPtest_real8 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @cosh({{%[A-Za-z0-9._]+}}) : (f64) -> f64 + +func.func @_QPtest_real4(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f32 { + %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @coshf(%1) : (f32) -> f32 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f32 +} +func.func @_QPtest_real8(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f64 { + %0 = fir.alloca f64 {bindc_name = "test_real8", uniq_name = "_QFtest_real8Etest_real8"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @cosh(%1) : (f64) -> f64 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f64 +} +func.func private @coshf(f32) -> f32 +func.func private @cosh(f64) -> f64 + //--- erf_fast.fir // RUN: fir-opt %t/erf_fast.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/erf_fast.fir // CHECK: @_QPtest_real4 @@ -1359,6 +1474,12 @@ // CHECK: @_QPtest_real8 // CHECK: {{%[A-Za-z0-9._]+}} = "llvm.intr.copysign"({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f64, f64) -> f64 +// CHECK: @_QPtest_real10 +// CHECK: {{%[A-Za-z0-9._]+}} = "llvm.intr.copysign"({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f80, f80) -> f80 + +// CHECK: @_QPtest_real16 +// CHECK: {{%[A-Za-z0-9._]+}} = "llvm.intr.copysign"({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f128, f128) -> f128 + func.func @_QPtest_real4(%arg0: !fir.ref {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "y"}) -> f32 { %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"} %1 = fir.load %arg0 : !fir.ref @@ -1377,6 +1498,24 @@ %4 = fir.load %0 : !fir.ref return %4 : f64 } +func.func @_QPtest_real10(%arg0: !fir.ref {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "y"}) -> f80 { + %0 = fir.alloca f80 {bindc_name = "test_real10", uniq_name = "_QFtest_real10Etest_real10"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.load %arg1 : !fir.ref + %3 = math.copysign %1, %2 : f80 + fir.store %3 to %0 : !fir.ref + %4 = fir.load %0 : !fir.ref + return %4 : f80 +} +func.func @_QPtest_real16(%arg0: !fir.ref {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "y"}) -> f128 { + %0 = fir.alloca f128 {bindc_name = "test_real16", uniq_name = "_QFtest_real16Etest_real16"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.load %arg1 : !fir.ref + %3 = math.copysign %1, %2 : f128 + fir.store %3 to %0 : !fir.ref + %4 = fir.load %0 : !fir.ref + return %4 : f128 +} //--- sign_relaxed.fir // RUN: fir-opt %t/sign_relaxed.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/sign_relaxed.fir @@ -1386,6 +1525,12 @@ // CHECK: @_QPtest_real8 // CHECK: {{%[A-Za-z0-9._]+}} = "llvm.intr.copysign"({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f64, f64) -> f64 +// CHECK: @_QPtest_real10 +// CHECK: {{%[A-Za-z0-9._]+}} = "llvm.intr.copysign"({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f80, f80) -> f80 + +// CHECK: @_QPtest_real16 +// CHECK: {{%[A-Za-z0-9._]+}} = "llvm.intr.copysign"({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f128, f128) -> f128 + func.func @_QPtest_real4(%arg0: !fir.ref {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "y"}) -> f32 { %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"} %1 = fir.load %arg0 : !fir.ref @@ -1404,6 +1549,24 @@ %4 = fir.load %0 : !fir.ref return %4 : f64 } +func.func @_QPtest_real10(%arg0: !fir.ref {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "y"}) -> f80 { + %0 = fir.alloca f80 {bindc_name = "test_real10", uniq_name = "_QFtest_real10Etest_real10"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.load %arg1 : !fir.ref + %3 = math.copysign %1, %2 : f80 + fir.store %3 to %0 : !fir.ref + %4 = fir.load %0 : !fir.ref + return %4 : f80 +} +func.func @_QPtest_real16(%arg0: !fir.ref {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "y"}) -> f128 { + %0 = fir.alloca f128 {bindc_name = "test_real16", uniq_name = "_QFtest_real16Etest_real16"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.load %arg1 : !fir.ref + %3 = math.copysign %1, %2 : f128 + fir.store %3 to %0 : !fir.ref + %4 = fir.load %0 : !fir.ref + return %4 : f128 +} //--- sign_precise.fir // RUN: fir-opt %t/sign_precise.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/sign_precise.fir @@ -1413,6 +1576,12 @@ // CHECK: @_QPtest_real8 // CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @copysign({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f64, f64) -> f64 +// CHECK: @_QPtest_real10 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @copysignl({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f80, f80) -> f80 + +// CHECK: @_QPtest_real16 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @llvm.copysign.f128({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f128, f128) -> f128 + func.func @_QPtest_real4(%arg0: !fir.ref {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "y"}) -> f32 { %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"} %1 = fir.load %arg0 : !fir.ref @@ -1431,8 +1600,28 @@ %4 = fir.load %0 : !fir.ref return %4 : f64 } +func.func @_QPtest_real10(%arg0: !fir.ref {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "y"}) -> f80 { + %0 = fir.alloca f80 {bindc_name = "test_real10", uniq_name = "_QFtest_real10Etest_real10"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.load %arg1 : !fir.ref + %3 = fir.call @copysignl(%1, %2) : (f80, f80) -> f80 + fir.store %3 to %0 : !fir.ref + %4 = fir.load %0 : !fir.ref + return %4 : f80 +} +func.func @_QPtest_real16(%arg0: !fir.ref {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "y"}) -> f128 { + %0 = fir.alloca f128 {bindc_name = "test_real16", uniq_name = "_QFtest_real16Etest_real16"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.load %arg1 : !fir.ref + %3 = fir.call @llvm.copysign.f128(%1, %2) : (f128, f128) -> f128 + fir.store %3 to %0 : !fir.ref + %4 = fir.load %0 : !fir.ref + return %4 : f128 +} func.func private @copysignf(f32, f32) -> f32 func.func private @copysign(f64, f64) -> f64 +func.func private @copysignl(f80, f80) -> f80 +func.func private @llvm.copysign.f128(f128, f128) -> f128 //--- sin_fast.fir // RUN: fir-opt %t/sin_fast.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/sin_fast.fir @@ -1511,6 +1700,87 @@ func.func private @sinf(f32) -> f32 func.func private @sin(f64) -> f64 +//--- sinh_fast.fir +// RUN: fir-opt %t/sinh_fast.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/sinh_fast.fir +// CHECK: @_QPtest_real4 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @sinhf({{%[A-Za-z0-9._]+}}) : (f32) -> f32 + +// CHECK: @_QPtest_real8 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @sinh({{%[A-Za-z0-9._]+}}) : (f64) -> f64 + +func.func @_QPtest_real4(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f32 { + %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @sinhf(%1) : (f32) -> f32 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f32 +} +func.func @_QPtest_real8(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f64 { + %0 = fir.alloca f64 {bindc_name = "test_real8", uniq_name = "_QFtest_real8Etest_real8"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @sinh(%1) : (f64) -> f64 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f64 +} +func.func private @sinhf(f32) -> f32 +func.func private @sinh(f64) -> f64 + +//--- sinh_relaxed.fir +// RUN: fir-opt %t/sinh_relaxed.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/sinh_relaxed.fir +// CHECK: @_QPtest_real4 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @sinhf({{%[A-Za-z0-9._]+}}) : (f32) -> f32 + +// CHECK: @_QPtest_real8 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @sinh({{%[A-Za-z0-9._]+}}) : (f64) -> f64 + +func.func @_QPtest_real4(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f32 { + %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @sinhf(%1) : (f32) -> f32 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f32 +} +func.func @_QPtest_real8(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f64 { + %0 = fir.alloca f64 {bindc_name = "test_real8", uniq_name = "_QFtest_real8Etest_real8"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @sinh(%1) : (f64) -> f64 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f64 +} +func.func private @sinhf(f32) -> f32 +func.func private @sinh(f64) -> f64 + +//--- sinh_precise.fir +// RUN: fir-opt %t/sinh_precise.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/sinh_precise.fir +// CHECK: @_QPtest_real4 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @sinhf({{%[A-Za-z0-9._]+}}) : (f32) -> f32 + +// CHECK: @_QPtest_real8 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @sinh({{%[A-Za-z0-9._]+}}) : (f64) -> f64 + +func.func @_QPtest_real4(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f32 { + %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @sinhf(%1) : (f32) -> f32 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f32 +} +func.func @_QPtest_real8(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f64 { + %0 = fir.alloca f64 {bindc_name = "test_real8", uniq_name = "_QFtest_real8Etest_real8"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @sinh(%1) : (f64) -> f64 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f64 +} +func.func private @sinhf(f32) -> f32 +func.func private @sinh(f64) -> f64 + //--- tanh_fast.fir // RUN: fir-opt %t/tanh_fast.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/tanh_fast.fir // CHECK: @_QPtest_real4 @@ -1588,3 +1858,80 @@ func.func private @tanhf(f32) -> f32 func.func private @tanh(f64) -> f64 +//--- tan_fast.fir +// RUN: fir-opt %t/tan_fast.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/tan_fast.fir +// CHECK: @_QPtest_real4 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @tanf({{%[A-Za-z0-9._]+}}) : (f32) -> f32 + +// CHECK: @_QPtest_real8 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @tan({{%[A-Za-z0-9._]+}}) : (f64) -> f64 + +func.func @_QPtest_real4(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f32 { + %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"} + %1 = fir.load %arg0 : !fir.ref + %2 = math.tan %1 : f32 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f32 +} +func.func @_QPtest_real8(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f64 { + %0 = fir.alloca f64 {bindc_name = "test_real8", uniq_name = "_QFtest_real8Etest_real8"} + %1 = fir.load %arg0 : !fir.ref + %2 = math.tan %1 : f64 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f64 +} + +//--- tan_relaxed.fir +// RUN: fir-opt %t/tan_relaxed.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/tan_relaxed.fir +// CHECK: @_QPtest_real4 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @tanf({{%[A-Za-z0-9._]+}}) : (f32) -> f32 + +// CHECK: @_QPtest_real8 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @tan({{%[A-Za-z0-9._]+}}) : (f64) -> f64 + +func.func @_QPtest_real4(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f32 { + %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"} + %1 = fir.load %arg0 : !fir.ref + %2 = math.tan %1 : f32 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f32 +} +func.func @_QPtest_real8(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f64 { + %0 = fir.alloca f64 {bindc_name = "test_real8", uniq_name = "_QFtest_real8Etest_real8"} + %1 = fir.load %arg0 : !fir.ref + %2 = math.tan %1 : f64 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f64 +} + +//--- tan_precise.fir +// RUN: fir-opt %t/tan_precise.fir --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" | FileCheck %t/tan_precise.fir +// CHECK: @_QPtest_real4 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @tanf({{%[A-Za-z0-9._]+}}) : (f32) -> f32 + +// CHECK: @_QPtest_real8 +// CHECK: {{%[A-Za-z0-9._]+}} = llvm.call @tan({{%[A-Za-z0-9._]+}}) : (f64) -> f64 + +func.func @_QPtest_real4(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f32 { + %0 = fir.alloca f32 {bindc_name = "test_real4", uniq_name = "_QFtest_real4Etest_real4"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @tanf(%1) : (f32) -> f32 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f32 +} +func.func @_QPtest_real8(%arg0: !fir.ref {fir.bindc_name = "x"}) -> f64 { + %0 = fir.alloca f64 {bindc_name = "test_real8", uniq_name = "_QFtest_real8Etest_real8"} + %1 = fir.load %arg0 : !fir.ref + %2 = fir.call @tan(%1) : (f64) -> f64 + fir.store %2 to %0 : !fir.ref + %3 = fir.load %0 : !fir.ref + return %3 : f64 +} +func.func private @tanf(f32) -> f32 +func.func private @tan(f64) -> f64 + diff --git a/flang/test/Lower/Intrinsics/abs.f90 b/flang/test/Lower/Intrinsics/abs.f90 --- a/flang/test/Lower/Intrinsics/abs.f90 +++ b/flang/test/Lower/Intrinsics/abs.f90 @@ -79,6 +79,17 @@ b = abs(a) end subroutine +! CHECK-LABEL: func @_QPabs_testr16( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref{{.*}}, %[[VAL_1:.*]]: !fir.ref{{.*}}) { +subroutine abs_testr16(a, b) +! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref +! CHECK: %[[VAL_3:.*]] = fir.call @llvm.fabs.f128(%[[VAL_2]]) : (f128) -> f128 +! CHECK: fir.store %[[VAL_3]] to %[[VAL_1]] : !fir.ref +! CHECK: return + real(kind=16) :: a, b + b = abs(a) +end subroutine + ! CHECK-LABEL: func @_QPabs_testzr( ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>{{.*}}, %[[VAL_1:.*]]: !fir.ref{{.*}}) { subroutine abs_testzr(a, b) diff --git a/flang/test/Lower/late-math-lowering.f90 b/flang/test/Lower/late-math-lowering.f90 --- a/flang/test/Lower/late-math-lowering.f90 +++ b/flang/test/Lower/late-math-lowering.f90 @@ -28,6 +28,15 @@ ! RELAXED: {{%[A-Za-z0-9._]+}} = math.abs {{%[A-Za-z0-9._]+}} : f64 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @fabs({{%[A-Za-z0-9._]+}}) : (f64) -> f64 +function test_real16(x) + real(16) :: x, test_real16 + test_real16 = abs(x) +end function +! ALL-LABEL: @_QPtest_real16 +! FAST: {{%[A-Za-z0-9._]+}} = math.abs {{%[A-Za-z0-9._]+}} : f128 +! RELAXED: {{%[A-Za-z0-9._]+}} = math.abs {{%[A-Za-z0-9._]+}} : f128 +! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @llvm.fabs.f128({{%[A-Za-z0-9._]+}}) : (f128) -> f128 + function test_complex4(c) complex(4) :: c, test_complex4 test_complex4 = abs(c) @@ -208,6 +217,30 @@ ! RELAXED: {{%[A-Za-z0-9._]+}} = math.cos {{%[A-Za-z0-9._]+}} : f64 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @cos({{%[A-Za-z0-9._]+}}) : (f64) -> f64 +//--- cosh.f90 +! RUN: bbc -emit-fir %t/cosh.f90 -o - --lower-math-early=false --math-runtime=fast | FileCheck --check-prefixes=ALL %t/cosh.f90 +! RUN: %flang_fc1 -emit-fir -mllvm -lower-math-early=false -mllvm -math-runtime=fast %t/cosh.f90 -o - | FileCheck --check-prefixes=ALL %t/cosh.f90 +! RUN: bbc -emit-fir %t/cosh.f90 -o - --lower-math-early=false --math-runtime=relaxed | FileCheck --check-prefixes=ALL %t/cosh.f90 +! RUN: %flang_fc1 -emit-fir -mllvm -lower-math-early=false -mllvm -math-runtime=relaxed %t/cosh.f90 -o - | FileCheck --check-prefixes=ALL %t/cosh.f90 +! RUN: bbc -emit-fir %t/cosh.f90 -o - --lower-math-early=false --math-runtime=precise | FileCheck --check-prefixes=ALL %t/cosh.f90 +! RUN: %flang_fc1 -emit-fir -mllvm -lower-math-early=false -mllvm -math-runtime=precise %t/cosh.f90 -o - | FileCheck --check-prefixes=ALL %t/cosh.f90 + +function test_real4(x) + real :: x, test_real4 + test_real4 = cosh(x) +end function + +! ALL-LABEL: @_QPtest_real4 +! ALL: {{%[A-Za-z0-9._]+}} = fir.call @coshf({{%[A-Za-z0-9._]+}}) : (f32) -> f32 + +function test_real8(x) + real(8) :: x, test_real8 + test_real8 = cosh(x) +end function + +! ALL-LABEL: @_QPtest_real8 +! ALL: {{%[A-Za-z0-9._]+}} = fir.call @cosh({{%[A-Za-z0-9._]+}}) : (f64) -> f64 + //--- erf.f90 ! RUN: bbc -emit-fir %t/erf.f90 -o - --lower-math-early=false --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/erf.f90 ! RUN: %flang_fc1 -emit-fir -mllvm -lower-math-early=false -mllvm -math-runtime=fast %t/erf.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/erf.f90 @@ -440,6 +473,26 @@ ! RELAXED: {{%[A-Za-z0-9._]+}} = math.copysign {{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}} : f64 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @copysign({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f64, f64) -> f64 +function test_real10(x, y) + real(10) :: x, y, test_real10 + test_real10 = sign(x, y) +end function + +! ALL-LABEL: @_QPtest_real10 +! FAST: {{%[A-Za-z0-9._]+}} = math.copysign {{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}} : f80 +! RELAXED: {{%[A-Za-z0-9._]+}} = math.copysign {{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}} : f80 +! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @copysignl({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f80, f80) -> f80 + +function test_real16(x, y) + real(16) :: x, y, test_real16 + test_real16 = sign(x, y) +end function + +! ALL-LABEL: @_QPtest_real16 +! FAST: {{%[A-Za-z0-9._]+}} = math.copysign {{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}} : f128 +! RELAXED: {{%[A-Za-z0-9._]+}} = math.copysign {{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}} : f128 +! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @llvm.copysign.f128({{%[A-Za-z0-9._]+}}, {{%[A-Za-z0-9._]+}}) : (f128, f128) -> f128 + //--- sin.f90 ! RUN: bbc -emit-fir %t/sin.f90 -o - --lower-math-early=false --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/sin.f90 ! RUN: %flang_fc1 -emit-fir -mllvm -lower-math-early=false -mllvm -math-runtime=fast %t/sin.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/sin.f90 @@ -468,6 +521,30 @@ ! RELAXED: {{%[A-Za-z0-9._]+}} = math.sin {{%[A-Za-z0-9._]+}} : f64 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @sin({{%[A-Za-z0-9._]+}}) : (f64) -> f64 +//--- sinh.f90 +! RUN: bbc -emit-fir %t/sinh.f90 -o - --lower-math-early=false --math-runtime=fast | FileCheck --check-prefixes=ALL %t/sinh.f90 +! RUN: %flang_fc1 -emit-fir -mllvm -lower-math-early=false -mllvm -math-runtime=fast %t/sinh.f90 -o - | FileCheck --check-prefixes=ALL %t/sinh.f90 +! RUN: bbc -emit-fir %t/sinh.f90 -o - --lower-math-early=false --math-runtime=relaxed | FileCheck --check-prefixes=ALL %t/sinh.f90 +! RUN: %flang_fc1 -emit-fir -mllvm -lower-math-early=false -mllvm -math-runtime=relaxed %t/sinh.f90 -o - | FileCheck --check-prefixes=ALL %t/sinh.f90 +! RUN: bbc -emit-fir %t/sinh.f90 -o - --lower-math-early=false --math-runtime=precise | FileCheck --check-prefixes=ALL %t/sinh.f90 +! RUN: %flang_fc1 -emit-fir -mllvm -lower-math-early=false -mllvm -math-runtime=precise %t/sinh.f90 -o - | FileCheck --check-prefixes=ALL %t/sinh.f90 + +function test_real4(x) + real :: x, test_real4 + test_real4 = sinh(x) +end function + +! ALL-LABEL: @_QPtest_real4 +! ALL: {{%[A-Za-z0-9._]+}} = fir.call @sinhf({{%[A-Za-z0-9._]+}}) : (f32) -> f32 + +function test_real8(x) + real(8) :: x, test_real8 + test_real8 = sinh(x) +end function + +! ALL-LABEL: @_QPtest_real8 +! ALL: {{%[A-Za-z0-9._]+}} = fir.call @sinh({{%[A-Za-z0-9._]+}}) : (f64) -> f64 + //--- tanh.f90 ! RUN: bbc -emit-fir %t/tanh.f90 -o - --lower-math-early=false --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/tanh.f90 ! RUN: %flang_fc1 -emit-fir -mllvm -lower-math-early=false -mllvm -math-runtime=fast %t/tanh.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/tanh.f90 @@ -495,3 +572,31 @@ ! FAST: {{%[A-Za-z0-9._]+}} = math.tanh {{%[A-Za-z0-9._]+}} : f64 ! RELAXED: {{%[A-Za-z0-9._]+}} = math.tanh {{%[A-Za-z0-9._]+}} : f64 ! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @tanh({{%[A-Za-z0-9._]+}}) : (f64) -> f64 + +//--- tan.f90 +! RUN: bbc -emit-fir %t/tan.f90 -o - --lower-math-early=false --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/tan.f90 +! RUN: %flang_fc1 -emit-fir -mllvm -lower-math-early=false -mllvm -math-runtime=fast %t/tan.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/tan.f90 +! RUN: bbc -emit-fir %t/tan.f90 -o - --lower-math-early=false --math-runtime=relaxed | FileCheck --check-prefixes=ALL,RELAXED %t/tan.f90 +! RUN: %flang_fc1 -emit-fir -mllvm -lower-math-early=false -mllvm -math-runtime=relaxed %t/tan.f90 -o - | FileCheck --check-prefixes=ALL,RELAXED %t/tan.f90 +! RUN: bbc -emit-fir %t/tan.f90 -o - --lower-math-early=false --math-runtime=precise | FileCheck --check-prefixes=ALL,PRECISE %t/tan.f90 +! RUN: %flang_fc1 -emit-fir -mllvm -lower-math-early=false -mllvm -math-runtime=precise %t/tan.f90 -o - | FileCheck --check-prefixes=ALL,PRECISE %t/tan.f90 + +function test_real4(x) + real :: x, test_real4 + test_real4 = tan(x) +end function + +! ALL-LABEL: @_QPtest_real4 +! FAST: {{%[A-Za-z0-9._]+}} = math.tan {{%[A-Za-z0-9._]+}} : f32 +! RELAXED: {{%[A-Za-z0-9._]+}} = math.tan {{%[A-Za-z0-9._]+}} : f32 +! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @tanf({{%[A-Za-z0-9._]+}}) : (f32) -> f32 + +function test_real8(x) + real(8) :: x, test_real8 + test_real8 = tan(x) +end function + +! ALL-LABEL: @_QPtest_real8 +! FAST: {{%[A-Za-z0-9._]+}} = math.tan {{%[A-Za-z0-9._]+}} : f64 +! RELAXED: {{%[A-Za-z0-9._]+}} = math.tan {{%[A-Za-z0-9._]+}} : f64 +! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @tan({{%[A-Za-z0-9._]+}}) : (f64) -> f64