aboutsummaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
authorFarzon Lotfi <1802579+farzonl@users.noreply.github.com>2024-06-20 10:34:23 -0400
committerGitHub <noreply@github.com>2024-06-20 10:34:23 -0400
commit2ae6889d3f6c6bbe8390d6b1686c6583492b44a2 (patch)
treec877ddabd514623d8f5453f445404053ee62ff9f /llvm
parentfa6d38d61afff695357977853ec17d0b7cc8e975 (diff)
downloadllvm-2ae6889d3f6c6bbe8390d6b1686c6583492b44a2.zip
llvm-2ae6889d3f6c6bbe8390d6b1686c6583492b44a2.tar.gz
llvm-2ae6889d3f6c6bbe8390d6b1686c6583492b44a2.tar.bz2
[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.
Diffstat (limited to 'llvm')
-rw-r--r--llvm/docs/GlobalISel/GenericOpcode.rst9
-rw-r--r--llvm/include/llvm/Support/TargetOpcodes.def20
-rw-r--r--llvm/include/llvm/Target/GenericOpcodes.td42
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp12
-rw-r--r--llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp12
-rw-r--r--llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp6
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir18
-rw-r--r--llvm/test/CodeGen/SPIRV/hlsl-intrinsics/acos.ll45
-rw-r--r--llvm/test/CodeGen/SPIRV/hlsl-intrinsics/asin.ll45
-rw-r--r--llvm/test/CodeGen/SPIRV/hlsl-intrinsics/atan.ll45
-rw-r--r--llvm/test/CodeGen/SPIRV/hlsl-intrinsics/cosh.ll45
-rw-r--r--llvm/test/CodeGen/SPIRV/hlsl-intrinsics/sinh.ll45
-rw-r--r--llvm/test/CodeGen/SPIRV/hlsl-intrinsics/tanh.ll45
13 files changed, 386 insertions, 3 deletions
diff --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst
index 5c28c6f..42f5634 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 559a588..df4b264 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 c40498e..4abffe6 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 7efcf21..c06b35a 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 b9e5569..d7b96b2 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 57fbf3b..6c7c3af 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 04c9a08..f034919 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 0000000..fb0ced3
--- /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 0000000..a842417
--- /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 0000000..65975fc
--- /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 0000000..35ba1d6
--- /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 0000000..55e050c
--- /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 0000000..8cddc0f
--- /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>)