From 2a824e9d38b53fb7be467372bcf32c4524f051ee Mon Sep 17 00:00:00 2001 From: Farzon Lotfi <1802579+farzonl@users.noreply.github.com> Date: Thu, 20 Jun 2024 10:34:23 -0400 Subject: [PATCH] [SPIRV] Add trig function lowering (#95973) This change is part of this proposal: https://discourse.llvm.org/t/rfc-all-the-math-intrinsics/78294 This is part 2 of 4 PRs. It sets the ground work for adding the intrinsics. Add SPIRV Lower for `acos`, `asin`, `atan`, `cosh`, `sinh`, and `tanh` https://github.com/llvm/llvm-project/issues/70079 https://github.com/llvm/llvm-project/issues/70080 https://github.com/llvm/llvm-project/issues/70081 https://github.com/llvm/llvm-project/issues/70083 https://github.com/llvm/llvm-project/issues/70084 https://github.com/llvm/llvm-project/issues/95966 There isn't any aarch64 change in this pr, but when you add a target opcode it is visible in there validaiton tests. --- llvm/docs/GlobalISel/GenericOpcode.rst | 9 +++- llvm/include/llvm/Support/TargetOpcodes.def | 20 ++++++++- llvm/include/llvm/Target/GenericOpcodes.td | 42 +++++++++++++++++ llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 12 +++++ .../Target/SPIRV/SPIRVInstructionSelector.cpp | 12 +++++ llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 6 +++ .../GlobalISel/legalizer-info-validation.mir | 18 ++++++++ .../CodeGen/SPIRV/hlsl-intrinsics/acos.ll | 45 +++++++++++++++++++ .../CodeGen/SPIRV/hlsl-intrinsics/asin.ll | 45 +++++++++++++++++++ .../CodeGen/SPIRV/hlsl-intrinsics/atan.ll | 45 +++++++++++++++++++ .../CodeGen/SPIRV/hlsl-intrinsics/cosh.ll | 45 +++++++++++++++++++ .../CodeGen/SPIRV/hlsl-intrinsics/sinh.ll | 45 +++++++++++++++++++ .../CodeGen/SPIRV/hlsl-intrinsics/tanh.ll | 45 +++++++++++++++++++ 13 files changed, 386 insertions(+), 3 deletions(-) create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/acos.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/asin.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/atan.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/cosh.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/sinh.ll create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/tanh.ll diff --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst index 5c28c6fcd30fb..42f56348885b4 100644 --- a/llvm/docs/GlobalISel/GenericOpcode.rst +++ b/llvm/docs/GlobalISel/GenericOpcode.rst @@ -592,11 +592,16 @@ G_FLOG, G_FLOG2, G_FLOG10 Calculate the base-e, base-2, or base-10 respectively. -G_FCEIL, G_FCOS, G_FSIN, G_FTAN, G_FSQRT, G_FFLOOR, G_FRINT, G_FNEARBYINT -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +G_FCEIL, G_FSQRT, G_FFLOOR, G_FRINT, G_FNEARBYINT +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ These correspond to the standard C functions of the same name. +G_FCOS, G_FSIN, G_FTAN, G_FACOS, G_FASIN, G_FATAN, G_FCOSH, G_FSINH, G_FTANH +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +These correspond to the standard C trigonometry functions of the same name. + G_INTRINSIC_TRUNC ^^^^^^^^^^^^^^^^^ diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def index 559a588c25148..df4b264af72a8 100644 --- a/llvm/include/llvm/Support/TargetOpcodes.def +++ b/llvm/include/llvm/Support/TargetOpcodes.def @@ -781,9 +781,27 @@ HANDLE_TARGET_OPCODE(G_FCOS) /// Floating point sine. HANDLE_TARGET_OPCODE(G_FSIN) -/// Floating point Tangent. +/// Floating point tangent. HANDLE_TARGET_OPCODE(G_FTAN) +/// Floating point arccosine. +HANDLE_TARGET_OPCODE(G_FACOS) + +/// Floating point arcsine. +HANDLE_TARGET_OPCODE(G_FASIN) + +/// Floating point arctangent. +HANDLE_TARGET_OPCODE(G_FATAN) + +/// Floating point hyperbolic cosine. +HANDLE_TARGET_OPCODE(G_FCOSH) + +/// Floating point hyperbolic sine. +HANDLE_TARGET_OPCODE(G_FSINH) + +/// Floating point hyperbolic tangent. +HANDLE_TARGET_OPCODE(G_FTANH) + /// Floating point square root. HANDLE_TARGET_OPCODE(G_FSQRT) diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index c40498e554215..4abffe6476c85 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -995,6 +995,48 @@ def G_FTAN : GenericInstruction { let hasSideEffects = false; } +// Floating point arccosine of a value. +def G_FACOS : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1); + let hasSideEffects = false; +} + +// Floating point arcsine of a value. +def G_FASIN : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1); + let hasSideEffects = false; +} + +// Floating point arctangent of a value. +def G_FATAN : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1); + let hasSideEffects = false; +} + +// Floating point hyperbolic cosine of a value. +def G_FCOSH : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1); + let hasSideEffects = false; +} + +// Floating point hyperbolic sine of a value. +def G_FSINH : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1); + let hasSideEffects = false; +} + +// Floating point hyperbolic tangent of a value. +def G_FTANH : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1); + let hasSideEffects = false; +} + // Floating point square root of a value. // This returns NaN for negative nonzero values. // NOTE: Unlike libm sqrt(), this never sets errno. In all other respects it's diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 7efcf21460260..c06b35a98e434 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1879,6 +1879,12 @@ unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) { switch (ID) { default: break; + case Intrinsic::acos: + return TargetOpcode::G_FACOS; + case Intrinsic::asin: + return TargetOpcode::G_FASIN; + case Intrinsic::atan: + return TargetOpcode::G_FATAN; case Intrinsic::bswap: return TargetOpcode::G_BSWAP; case Intrinsic::bitreverse: @@ -1891,6 +1897,8 @@ unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) { return TargetOpcode::G_FCEIL; case Intrinsic::cos: return TargetOpcode::G_FCOS; + case Intrinsic::cosh: + return TargetOpcode::G_FCOSH; case Intrinsic::ctpop: return TargetOpcode::G_CTPOP; case Intrinsic::exp: @@ -1939,10 +1947,14 @@ unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) { return TargetOpcode::G_INTRINSIC_ROUNDEVEN; case Intrinsic::sin: return TargetOpcode::G_FSIN; + case Intrinsic::sinh: + return TargetOpcode::G_FSINH; case Intrinsic::sqrt: return TargetOpcode::G_FSQRT; case Intrinsic::tan: return TargetOpcode::G_FTAN; + case Intrinsic::tanh: + return TargetOpcode::G_FTANH; case Intrinsic::trunc: return TargetOpcode::G_INTRINSIC_TRUNC; case Intrinsic::readcyclecounter: diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index b9e5569029cfd..d7b96b28445d6 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -472,6 +472,18 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg, return selectExtInst(ResVReg, ResType, I, CL::sin, GL::Sin); case TargetOpcode::G_FTAN: return selectExtInst(ResVReg, ResType, I, CL::tan, GL::Tan); + case TargetOpcode::G_FACOS: + return selectExtInst(ResVReg, ResType, I, CL::acos, GL::Acos); + case TargetOpcode::G_FASIN: + return selectExtInst(ResVReg, ResType, I, CL::asin, GL::Asin); + case TargetOpcode::G_FATAN: + return selectExtInst(ResVReg, ResType, I, CL::atan, GL::Atan); + case TargetOpcode::G_FCOSH: + return selectExtInst(ResVReg, ResType, I, CL::cosh, GL::Cosh); + case TargetOpcode::G_FSINH: + return selectExtInst(ResVReg, ResType, I, CL::sinh, GL::Sinh); + case TargetOpcode::G_FTANH: + return selectExtInst(ResVReg, ResType, I, CL::tanh, GL::Tanh); case TargetOpcode::G_FSQRT: return selectExtInst(ResVReg, ResType, I, CL::sqrt, GL::Sqrt); diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp index 57fbf3b3f8f12..6c7c3af199652 100644 --- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp @@ -278,6 +278,12 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) { G_FCOS, G_FSIN, G_FTAN, + G_FACOS, + G_FASIN, + G_FATAN, + G_FCOSH, + G_FSINH, + G_FTANH, G_FSQRT, G_FFLOOR, G_FRINT, diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir index 04c9a08c50038..f03491924f7f4 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir @@ -678,6 +678,24 @@ # DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}} # DEBUG-NEXT: .. the first uncovered type index: 1, OK # DEBUG-NEXT: .. the first uncovered imm index: 0, OK +# DEBUG-NEXT: G_FACOS (opcode {{[0-9]+}}): 1 type index, 0 imm indices +# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: G_FASIN (opcode {{[0-9]+}}): 1 type index, 0 imm indices +# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: G_FATAN (opcode {{[0-9]+}}): 1 type index, 0 imm indices +# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: G_FCOSH (opcode {{[0-9]+}}): 1 type index, 0 imm indices +# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: G_FSINH (opcode {{[0-9]+}}): 1 type index, 0 imm indices +# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: G_FTANH (opcode {{[0-9]+}}): 1 type index, 0 imm indices +# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined # DEBUG-NEXT: G_FSQRT (opcode {{[0-9]+}}): 1 type index, 0 imm indices # DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}} # DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/acos.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/acos.ll new file mode 100644 index 0000000000000..fb0ced342aba3 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/acos.ll @@ -0,0 +1,45 @@ +; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450" +; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32 +; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16 +; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4 +; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4 + +define noundef float @acos_float(float noundef %a) { +entry: +; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Acos %[[#arg0]] + %elt.acos = call float @llvm.acos.f32(float %a) + ret float %elt.acos +} + +define noundef half @acos_half(half noundef %a) { +entry: +; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] Acos %[[#arg0]] + %elt.acos = call half @llvm.acos.f16(half %a) + ret half %elt.acos +} + +define noundef <4 x float> @acos_float4(<4 x float> noundef %a) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] Acos %[[#arg0]] + %elt.acos = call <4 x float> @llvm.acos.v4f32(<4 x float> %a) + ret <4 x float> %elt.acos +} + +define noundef <4 x half> @acos_half4(<4 x half> noundef %a) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] Acos %[[#arg0]] + %elt.acos = call <4 x half> @llvm.acos.v4f16(<4 x half> %a) + ret <4 x half> %elt.acos +} + +declare half @llvm.acos.f16(half) +declare float @llvm.acos.f32(float) +declare <4 x half> @llvm.acos.v4f16(<4 x half>) +declare <4 x float> @llvm.acos.v4f32(<4 x float>) diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/asin.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/asin.ll new file mode 100644 index 0000000000000..a8424170b26e3 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/asin.ll @@ -0,0 +1,45 @@ +; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450" +; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32 +; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16 +; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4 +; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4 + +define noundef float @asin_float(float noundef %a) { +entry: +; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Asin %[[#arg0]] + %elt.asin = call float @llvm.asin.f32(float %a) + ret float %elt.asin +} + +define noundef half @asin_half(half noundef %a) { +entry: +; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] Asin %[[#arg0]] + %elt.asin = call half @llvm.asin.f16(half %a) + ret half %elt.asin +} + +define noundef <4 x float> @asin_float4(<4 x float> noundef %a) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] Asin %[[#arg0]] + %elt.asin = call <4 x float> @llvm.asin.v4f32(<4 x float> %a) + ret <4 x float> %elt.asin +} + +define noundef <4 x half> @asin_half4(<4 x half> noundef %a) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] Asin %[[#arg0]] + %elt.asin = call <4 x half> @llvm.asin.v4f16(<4 x half> %a) + ret <4 x half> %elt.asin +} + +declare half @llvm.asin.f16(half) +declare float @llvm.asin.f32(float) +declare <4 x half> @llvm.asin.v4f16(<4 x half>) +declare <4 x float> @llvm.asin.v4f32(<4 x float>) diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/atan.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/atan.ll new file mode 100644 index 0000000000000..65975fc413e53 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/atan.ll @@ -0,0 +1,45 @@ +; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450" +; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32 +; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16 +; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4 +; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4 + +define noundef float @atan_float(float noundef %a) { +entry: +; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Atan %[[#arg0]] + %elt.atan = call float @llvm.atan.f32(float %a) + ret float %elt.atan +} + +define noundef half @atan_half(half noundef %a) { +entry: +; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] Atan %[[#arg0]] + %elt.atan = call half @llvm.atan.f16(half %a) + ret half %elt.atan +} + +define noundef <4 x float> @atan_float4(<4 x float> noundef %a) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] Atan %[[#arg0]] + %elt.atan = call <4 x float> @llvm.atan.v4f32(<4 x float> %a) + ret <4 x float> %elt.atan +} + +define noundef <4 x half> @atan_half4(<4 x half> noundef %a) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] Atan %[[#arg0]] + %elt.atan = call <4 x half> @llvm.atan.v4f16(<4 x half> %a) + ret <4 x half> %elt.atan +} + +declare half @llvm.atan.f16(half) +declare float @llvm.atan.f32(float) +declare <4 x half> @llvm.atan.v4f16(<4 x half>) +declare <4 x float> @llvm.atan.v4f32(<4 x float>) diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/cosh.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/cosh.ll new file mode 100644 index 0000000000000..35ba1d69d7cbb --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/cosh.ll @@ -0,0 +1,45 @@ +; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450" +; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32 +; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16 +; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4 +; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4 + +define noundef float @cosh_float(float noundef %a) { +entry: +; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Cosh %[[#arg0]] + %elt.cosh = call float @llvm.cosh.f32(float %a) + ret float %elt.cosh +} + +define noundef half @cosh_half(half noundef %a) { +entry: +; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] Cosh %[[#arg0]] + %elt.cosh = call half @llvm.cosh.f16(half %a) + ret half %elt.cosh +} + +define noundef <4 x float> @cosh_float4(<4 x float> noundef %a) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] Cosh %[[#arg0]] + %elt.cosh = call <4 x float> @llvm.cosh.v4f32(<4 x float> %a) + ret <4 x float> %elt.cosh +} + +define noundef <4 x half> @cosh_half4(<4 x half> noundef %a) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] Cosh %[[#arg0]] + %elt.cosh = call <4 x half> @llvm.cosh.v4f16(<4 x half> %a) + ret <4 x half> %elt.cosh +} + +declare half @llvm.cosh.f16(half) +declare float @llvm.cosh.f32(float) +declare <4 x half> @llvm.cosh.v4f16(<4 x half>) +declare <4 x float> @llvm.cosh.v4f32(<4 x float>) diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/sinh.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/sinh.ll new file mode 100644 index 0000000000000..55e050c5001bf --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/sinh.ll @@ -0,0 +1,45 @@ +; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450" +; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32 +; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16 +; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4 +; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4 + +define noundef float @sinh_float(float noundef %a) { +entry: +; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Sinh %[[#arg0]] + %elt.sinh = call float @llvm.sinh.f32(float %a) + ret float %elt.sinh +} + +define noundef half @sinh_half(half noundef %a) { +entry: +; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] Sinh %[[#arg0]] + %elt.sinh = call half @llvm.sinh.f16(half %a) + ret half %elt.sinh +} + +define noundef <4 x float> @sinh_float4(<4 x float> noundef %a) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] Sinh %[[#arg0]] + %elt.sinh = call <4 x float> @llvm.sinh.v4f32(<4 x float> %a) + ret <4 x float> %elt.sinh +} + +define noundef <4 x half> @sinh_half4(<4 x half> noundef %a) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] Sinh %[[#arg0]] + %elt.sinh = call <4 x half> @llvm.sinh.v4f16(<4 x half> %a) + ret <4 x half> %elt.sinh +} + +declare half @llvm.sinh.f16(half) +declare float @llvm.sinh.f32(float) +declare <4 x half> @llvm.sinh.v4f16(<4 x half>) +declare <4 x float> @llvm.sinh.v4f32(<4 x float>) diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/tanh.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/tanh.ll new file mode 100644 index 0000000000000..8cddc0fc090a7 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/tanh.ll @@ -0,0 +1,45 @@ +; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450" +; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32 +; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16 +; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4 +; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4 + +define noundef float @tanh_float(float noundef %a) { +entry: +; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Tanh %[[#arg0]] + %elt.tanh = call float @llvm.tanh.f32(float %a) + ret float %elt.tanh +} + +define noundef half @tanh_half(half noundef %a) { +entry: +; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] +; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] Tanh %[[#arg0]] + %elt.tanh = call half @llvm.tanh.f16(half %a) + ret half %elt.tanh +} + +define noundef <4 x float> @tanh_float4(<4 x float> noundef %a) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] Tanh %[[#arg0]] + %elt.tanh = call <4 x float> @llvm.tanh.v4f32(<4 x float> %a) + ret <4 x float> %elt.tanh +} + +define noundef <4 x half> @tanh_half4(<4 x half> noundef %a) { +entry: + ; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]] + ; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] Tanh %[[#arg0]] + %elt.tanh = call <4 x half> @llvm.tanh.v4f16(<4 x half> %a) + ret <4 x half> %elt.tanh +} + +declare half @llvm.tanh.f16(half) +declare float @llvm.tanh.f32(float) +declare <4 x half> @llvm.tanh.v4f16(<4 x half>) +declare <4 x float> @llvm.tanh.v4f32(<4 x float>)