[llvm] [SPIRV] Add trig function lowering (PR #95973)
Farzon Lotfi via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 19 12:11:15 PDT 2024
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/95973
>From 701edbe2f010abcbd479e19cbc8841d6473ae556 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Tue, 18 Jun 2024 15:07:03 -0400
Subject: [PATCH 1/2] [SPIRV] Add trig function lowering
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
---
llvm/docs/GlobalISel/GenericOpcode.rst | 4 +-
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, 381 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..7037455fdbf0b 100644
--- a/llvm/docs/GlobalISel/GenericOpcode.rst
+++ b/llvm/docs/GlobalISel/GenericOpcode.rst
@@ -592,8 +592,8 @@ 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_FCOS, G_FSIN, G_FTAN, G_FACOS, G_FASIN, G_FATAN, G_FCOSH, G_FSINH, G_FTANH, G_FSQRT, G_FFLOOR, G_FRINT, G_FNEARBYINT
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
These correspond to the standard C functions of the same name.
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>)
>From 67d6e5d53e9af3d279858158cc6d8ff2e2736e16 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Wed, 19 Jun 2024 15:10:52 -0400
Subject: [PATCH 2/2] split out trig funcs into own opcode docs line
---
llvm/docs/GlobalISel/GenericOpcode.rst | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst
index 7037455fdbf0b..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_FACOS, G_FASIN, G_FATAN, G_FCOSH, G_FSINH, G_FTANH, 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
^^^^^^^^^^^^^^^^^
More information about the llvm-commits
mailing list