Skip to content

Commit 2a824e9

Browse files
farzonlAlexisPerry
authored andcommitted
[SPIRV] Add trig function lowering (llvm#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` llvm#70079 llvm#70080 llvm#70081 llvm#70083 llvm#70084 llvm#95966 There isn't any aarch64 change in this pr, but when you add a target opcode it is visible in there validaiton tests.
1 parent fdd0e5d commit 2a824e9

File tree

13 files changed

+386
-3
lines changed

13 files changed

+386
-3
lines changed

llvm/docs/GlobalISel/GenericOpcode.rst

+7-2
Original file line numberDiff line numberDiff line change
@@ -592,11 +592,16 @@ G_FLOG, G_FLOG2, G_FLOG10
592592

593593
Calculate the base-e, base-2, or base-10 respectively.
594594

595-
G_FCEIL, G_FCOS, G_FSIN, G_FTAN, G_FSQRT, G_FFLOOR, G_FRINT, G_FNEARBYINT
596-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
595+
G_FCEIL, G_FSQRT, G_FFLOOR, G_FRINT, G_FNEARBYINT
596+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
597597

598598
These correspond to the standard C functions of the same name.
599599

600+
G_FCOS, G_FSIN, G_FTAN, G_FACOS, G_FASIN, G_FATAN, G_FCOSH, G_FSINH, G_FTANH
601+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
602+
603+
These correspond to the standard C trigonometry functions of the same name.
604+
600605
G_INTRINSIC_TRUNC
601606
^^^^^^^^^^^^^^^^^
602607

llvm/include/llvm/Support/TargetOpcodes.def

+19-1
Original file line numberDiff line numberDiff line change
@@ -781,9 +781,27 @@ HANDLE_TARGET_OPCODE(G_FCOS)
781781
/// Floating point sine.
782782
HANDLE_TARGET_OPCODE(G_FSIN)
783783

784-
/// Floating point Tangent.
784+
/// Floating point tangent.
785785
HANDLE_TARGET_OPCODE(G_FTAN)
786786

787+
/// Floating point arccosine.
788+
HANDLE_TARGET_OPCODE(G_FACOS)
789+
790+
/// Floating point arcsine.
791+
HANDLE_TARGET_OPCODE(G_FASIN)
792+
793+
/// Floating point arctangent.
794+
HANDLE_TARGET_OPCODE(G_FATAN)
795+
796+
/// Floating point hyperbolic cosine.
797+
HANDLE_TARGET_OPCODE(G_FCOSH)
798+
799+
/// Floating point hyperbolic sine.
800+
HANDLE_TARGET_OPCODE(G_FSINH)
801+
802+
/// Floating point hyperbolic tangent.
803+
HANDLE_TARGET_OPCODE(G_FTANH)
804+
787805
/// Floating point square root.
788806
HANDLE_TARGET_OPCODE(G_FSQRT)
789807

llvm/include/llvm/Target/GenericOpcodes.td

+42
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,48 @@ def G_FTAN : GenericInstruction {
995995
let hasSideEffects = false;
996996
}
997997

998+
// Floating point arccosine of a value.
999+
def G_FACOS : GenericInstruction {
1000+
let OutOperandList = (outs type0:$dst);
1001+
let InOperandList = (ins type0:$src1);
1002+
let hasSideEffects = false;
1003+
}
1004+
1005+
// Floating point arcsine of a value.
1006+
def G_FASIN : GenericInstruction {
1007+
let OutOperandList = (outs type0:$dst);
1008+
let InOperandList = (ins type0:$src1);
1009+
let hasSideEffects = false;
1010+
}
1011+
1012+
// Floating point arctangent of a value.
1013+
def G_FATAN : GenericInstruction {
1014+
let OutOperandList = (outs type0:$dst);
1015+
let InOperandList = (ins type0:$src1);
1016+
let hasSideEffects = false;
1017+
}
1018+
1019+
// Floating point hyperbolic cosine of a value.
1020+
def G_FCOSH : GenericInstruction {
1021+
let OutOperandList = (outs type0:$dst);
1022+
let InOperandList = (ins type0:$src1);
1023+
let hasSideEffects = false;
1024+
}
1025+
1026+
// Floating point hyperbolic sine of a value.
1027+
def G_FSINH : GenericInstruction {
1028+
let OutOperandList = (outs type0:$dst);
1029+
let InOperandList = (ins type0:$src1);
1030+
let hasSideEffects = false;
1031+
}
1032+
1033+
// Floating point hyperbolic tangent of a value.
1034+
def G_FTANH : GenericInstruction {
1035+
let OutOperandList = (outs type0:$dst);
1036+
let InOperandList = (ins type0:$src1);
1037+
let hasSideEffects = false;
1038+
}
1039+
9981040
// Floating point square root of a value.
9991041
// This returns NaN for negative nonzero values.
10001042
// NOTE: Unlike libm sqrt(), this never sets errno. In all other respects it's

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,12 @@ unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) {
18791879
switch (ID) {
18801880
default:
18811881
break;
1882+
case Intrinsic::acos:
1883+
return TargetOpcode::G_FACOS;
1884+
case Intrinsic::asin:
1885+
return TargetOpcode::G_FASIN;
1886+
case Intrinsic::atan:
1887+
return TargetOpcode::G_FATAN;
18821888
case Intrinsic::bswap:
18831889
return TargetOpcode::G_BSWAP;
18841890
case Intrinsic::bitreverse:
@@ -1891,6 +1897,8 @@ unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) {
18911897
return TargetOpcode::G_FCEIL;
18921898
case Intrinsic::cos:
18931899
return TargetOpcode::G_FCOS;
1900+
case Intrinsic::cosh:
1901+
return TargetOpcode::G_FCOSH;
18941902
case Intrinsic::ctpop:
18951903
return TargetOpcode::G_CTPOP;
18961904
case Intrinsic::exp:
@@ -1939,10 +1947,14 @@ unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) {
19391947
return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
19401948
case Intrinsic::sin:
19411949
return TargetOpcode::G_FSIN;
1950+
case Intrinsic::sinh:
1951+
return TargetOpcode::G_FSINH;
19421952
case Intrinsic::sqrt:
19431953
return TargetOpcode::G_FSQRT;
19441954
case Intrinsic::tan:
19451955
return TargetOpcode::G_FTAN;
1956+
case Intrinsic::tanh:
1957+
return TargetOpcode::G_FTANH;
19461958
case Intrinsic::trunc:
19471959
return TargetOpcode::G_INTRINSIC_TRUNC;
19481960
case Intrinsic::readcyclecounter:

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,18 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
472472
return selectExtInst(ResVReg, ResType, I, CL::sin, GL::Sin);
473473
case TargetOpcode::G_FTAN:
474474
return selectExtInst(ResVReg, ResType, I, CL::tan, GL::Tan);
475+
case TargetOpcode::G_FACOS:
476+
return selectExtInst(ResVReg, ResType, I, CL::acos, GL::Acos);
477+
case TargetOpcode::G_FASIN:
478+
return selectExtInst(ResVReg, ResType, I, CL::asin, GL::Asin);
479+
case TargetOpcode::G_FATAN:
480+
return selectExtInst(ResVReg, ResType, I, CL::atan, GL::Atan);
481+
case TargetOpcode::G_FCOSH:
482+
return selectExtInst(ResVReg, ResType, I, CL::cosh, GL::Cosh);
483+
case TargetOpcode::G_FSINH:
484+
return selectExtInst(ResVReg, ResType, I, CL::sinh, GL::Sinh);
485+
case TargetOpcode::G_FTANH:
486+
return selectExtInst(ResVReg, ResType, I, CL::tanh, GL::Tanh);
475487

476488
case TargetOpcode::G_FSQRT:
477489
return selectExtInst(ResVReg, ResType, I, CL::sqrt, GL::Sqrt);

llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,12 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
278278
G_FCOS,
279279
G_FSIN,
280280
G_FTAN,
281+
G_FACOS,
282+
G_FASIN,
283+
G_FATAN,
284+
G_FCOSH,
285+
G_FSINH,
286+
G_FTANH,
281287
G_FSQRT,
282288
G_FFLOOR,
283289
G_FRINT,

llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir

+18
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,24 @@
678678
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
679679
# DEBUG-NEXT: .. the first uncovered type index: 1, OK
680680
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
681+
# DEBUG-NEXT: G_FACOS (opcode {{[0-9]+}}): 1 type index, 0 imm indices
682+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
683+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
684+
# DEBUG-NEXT: G_FASIN (opcode {{[0-9]+}}): 1 type index, 0 imm indices
685+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
686+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
687+
# DEBUG-NEXT: G_FATAN (opcode {{[0-9]+}}): 1 type index, 0 imm indices
688+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
689+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
690+
# DEBUG-NEXT: G_FCOSH (opcode {{[0-9]+}}): 1 type index, 0 imm indices
691+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
692+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
693+
# DEBUG-NEXT: G_FSINH (opcode {{[0-9]+}}): 1 type index, 0 imm indices
694+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
695+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
696+
# DEBUG-NEXT: G_FTANH (opcode {{[0-9]+}}): 1 type index, 0 imm indices
697+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
698+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
681699
# DEBUG-NEXT: G_FSQRT (opcode {{[0-9]+}}): 1 type index, 0 imm indices
682700
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
683701
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
3+
4+
; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
5+
; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
6+
; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
7+
; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
8+
; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
9+
10+
define noundef float @acos_float(float noundef %a) {
11+
entry:
12+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
13+
; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Acos %[[#arg0]]
14+
%elt.acos = call float @llvm.acos.f32(float %a)
15+
ret float %elt.acos
16+
}
17+
18+
define noundef half @acos_half(half noundef %a) {
19+
entry:
20+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
21+
; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] Acos %[[#arg0]]
22+
%elt.acos = call half @llvm.acos.f16(half %a)
23+
ret half %elt.acos
24+
}
25+
26+
define noundef <4 x float> @acos_float4(<4 x float> noundef %a) {
27+
entry:
28+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
29+
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] Acos %[[#arg0]]
30+
%elt.acos = call <4 x float> @llvm.acos.v4f32(<4 x float> %a)
31+
ret <4 x float> %elt.acos
32+
}
33+
34+
define noundef <4 x half> @acos_half4(<4 x half> noundef %a) {
35+
entry:
36+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
37+
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] Acos %[[#arg0]]
38+
%elt.acos = call <4 x half> @llvm.acos.v4f16(<4 x half> %a)
39+
ret <4 x half> %elt.acos
40+
}
41+
42+
declare half @llvm.acos.f16(half)
43+
declare float @llvm.acos.f32(float)
44+
declare <4 x half> @llvm.acos.v4f16(<4 x half>)
45+
declare <4 x float> @llvm.acos.v4f32(<4 x float>)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
3+
4+
; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
5+
; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
6+
; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
7+
; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
8+
; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
9+
10+
define noundef float @asin_float(float noundef %a) {
11+
entry:
12+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
13+
; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Asin %[[#arg0]]
14+
%elt.asin = call float @llvm.asin.f32(float %a)
15+
ret float %elt.asin
16+
}
17+
18+
define noundef half @asin_half(half noundef %a) {
19+
entry:
20+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
21+
; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] Asin %[[#arg0]]
22+
%elt.asin = call half @llvm.asin.f16(half %a)
23+
ret half %elt.asin
24+
}
25+
26+
define noundef <4 x float> @asin_float4(<4 x float> noundef %a) {
27+
entry:
28+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
29+
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] Asin %[[#arg0]]
30+
%elt.asin = call <4 x float> @llvm.asin.v4f32(<4 x float> %a)
31+
ret <4 x float> %elt.asin
32+
}
33+
34+
define noundef <4 x half> @asin_half4(<4 x half> noundef %a) {
35+
entry:
36+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
37+
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] Asin %[[#arg0]]
38+
%elt.asin = call <4 x half> @llvm.asin.v4f16(<4 x half> %a)
39+
ret <4 x half> %elt.asin
40+
}
41+
42+
declare half @llvm.asin.f16(half)
43+
declare float @llvm.asin.f32(float)
44+
declare <4 x half> @llvm.asin.v4f16(<4 x half>)
45+
declare <4 x float> @llvm.asin.v4f32(<4 x float>)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
3+
4+
; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
5+
; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
6+
; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
7+
; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
8+
; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
9+
10+
define noundef float @atan_float(float noundef %a) {
11+
entry:
12+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
13+
; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Atan %[[#arg0]]
14+
%elt.atan = call float @llvm.atan.f32(float %a)
15+
ret float %elt.atan
16+
}
17+
18+
define noundef half @atan_half(half noundef %a) {
19+
entry:
20+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
21+
; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] Atan %[[#arg0]]
22+
%elt.atan = call half @llvm.atan.f16(half %a)
23+
ret half %elt.atan
24+
}
25+
26+
define noundef <4 x float> @atan_float4(<4 x float> noundef %a) {
27+
entry:
28+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
29+
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] Atan %[[#arg0]]
30+
%elt.atan = call <4 x float> @llvm.atan.v4f32(<4 x float> %a)
31+
ret <4 x float> %elt.atan
32+
}
33+
34+
define noundef <4 x half> @atan_half4(<4 x half> noundef %a) {
35+
entry:
36+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
37+
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] Atan %[[#arg0]]
38+
%elt.atan = call <4 x half> @llvm.atan.v4f16(<4 x half> %a)
39+
ret <4 x half> %elt.atan
40+
}
41+
42+
declare half @llvm.atan.f16(half)
43+
declare float @llvm.atan.f32(float)
44+
declare <4 x half> @llvm.atan.v4f16(<4 x half>)
45+
declare <4 x float> @llvm.atan.v4f32(<4 x float>)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
3+
4+
; CHECK-DAG: %[[#op_ext_glsl:]] = OpExtInstImport "GLSL.std.450"
5+
; CHECK-DAG: %[[#float_32:]] = OpTypeFloat 32
6+
; CHECK-DAG: %[[#float_16:]] = OpTypeFloat 16
7+
; CHECK-DAG: %[[#vec4_float_32:]] = OpTypeVector %[[#float_32]] 4
8+
; CHECK-DAG: %[[#vec4_float_16:]] = OpTypeVector %[[#float_16]] 4
9+
10+
define noundef float @cosh_float(float noundef %a) {
11+
entry:
12+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
13+
; CHECK: %[[#]] = OpExtInst %[[#float_32]] %[[#op_ext_glsl]] Cosh %[[#arg0]]
14+
%elt.cosh = call float @llvm.cosh.f32(float %a)
15+
ret float %elt.cosh
16+
}
17+
18+
define noundef half @cosh_half(half noundef %a) {
19+
entry:
20+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
21+
; CHECK: %[[#]] = OpExtInst %[[#float_16]] %[[#op_ext_glsl]] Cosh %[[#arg0]]
22+
%elt.cosh = call half @llvm.cosh.f16(half %a)
23+
ret half %elt.cosh
24+
}
25+
26+
define noundef <4 x float> @cosh_float4(<4 x float> noundef %a) {
27+
entry:
28+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
29+
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_32]] %[[#op_ext_glsl]] Cosh %[[#arg0]]
30+
%elt.cosh = call <4 x float> @llvm.cosh.v4f32(<4 x float> %a)
31+
ret <4 x float> %elt.cosh
32+
}
33+
34+
define noundef <4 x half> @cosh_half4(<4 x half> noundef %a) {
35+
entry:
36+
; CHECK: %[[#arg0:]] = OpFunctionParameter %[[#]]
37+
; CHECK: %[[#]] = OpExtInst %[[#vec4_float_16]] %[[#op_ext_glsl]] Cosh %[[#arg0]]
38+
%elt.cosh = call <4 x half> @llvm.cosh.v4f16(<4 x half> %a)
39+
ret <4 x half> %elt.cosh
40+
}
41+
42+
declare half @llvm.cosh.f16(half)
43+
declare float @llvm.cosh.f32(float)
44+
declare <4 x half> @llvm.cosh.v4f16(<4 x half>)
45+
declare <4 x float> @llvm.cosh.v4f32(<4 x float>)

0 commit comments

Comments
 (0)