Skip to content

Commit 0b58f34

Browse files
authored
[X86][CodeGen] Add base trig intrinsic lowerings (#96222)
This change is an implementation of #87367 investigation on supporting IEEE math operations as intrinsics. Which was discussed in this RFC: https://discourse.llvm.org/t/rfc-all-the-math-intrinsics/78294 This change adds constraint intrinsics and some lowering cases for `acos`, `asin`, `atan`, `cosh`, `sinh`, and `tanh`. The only x86 specific change was for f80. #70079 #70080 #70081 #70083 #70084 #95966 The x86 lowering is going to be done in three pr changes with this being the first. A second PR will be put up for Loop Vectorizing and then SLPVectorizer. The constraint intrinsics is also going to be in multiple parts, but just 2. This part covers just the llvm specific changes, part2 will cover clang specifc changes and legalization for backends than have special legalization requirements like aarch64 and wasm.
1 parent ea4ae25 commit 0b58f34

32 files changed

+3288
-8
lines changed

llvm/docs/LangRef.rst

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26535,6 +26535,219 @@ This function returns the tangent of the specified argument, returning the
2653526535
same values as the libm ``tan`` functions would, and handles error
2653626536
conditions in the same way.
2653726537

26538+
'``llvm.experimental.constrained.asin``' Intrinsic
26539+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26540+
26541+
Syntax:
26542+
"""""""
26543+
26544+
::
26545+
26546+
declare <type>
26547+
@llvm.experimental.constrained.asin(<type> <op1>,
26548+
metadata <rounding mode>,
26549+
metadata <exception behavior>)
26550+
26551+
Overview:
26552+
"""""""""
26553+
26554+
The '``llvm.experimental.constrained.asin``' intrinsic returns the arcsine of the
26555+
first operand.
26556+
26557+
Arguments:
26558+
""""""""""
26559+
26560+
The first argument and the return type are floating-point numbers of the same
26561+
type.
26562+
26563+
The second and third arguments specify the rounding mode and exception
26564+
behavior as described above.
26565+
26566+
Semantics:
26567+
""""""""""
26568+
26569+
This function returns the arcsine of the specified operand, returning the
26570+
same values as the libm ``asin`` functions would, and handles error
26571+
conditions in the same way.
26572+
26573+
26574+
'``llvm.experimental.constrained.acos``' Intrinsic
26575+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26576+
26577+
Syntax:
26578+
"""""""
26579+
26580+
::
26581+
26582+
declare <type>
26583+
@llvm.experimental.constrained.acos(<type> <op1>,
26584+
metadata <rounding mode>,
26585+
metadata <exception behavior>)
26586+
26587+
Overview:
26588+
"""""""""
26589+
26590+
The '``llvm.experimental.constrained.acos``' intrinsic returns the arccosine of the
26591+
first operand.
26592+
26593+
Arguments:
26594+
""""""""""
26595+
26596+
The first argument and the return type are floating-point numbers of the same
26597+
type.
26598+
26599+
The second and third arguments specify the rounding mode and exception
26600+
behavior as described above.
26601+
26602+
Semantics:
26603+
""""""""""
26604+
26605+
This function returns the arccosine of the specified operand, returning the
26606+
same values as the libm ``acos`` functions would, and handles error
26607+
conditions in the same way.
26608+
26609+
26610+
'``llvm.experimental.constrained.atan``' Intrinsic
26611+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26612+
26613+
Syntax:
26614+
"""""""
26615+
26616+
::
26617+
26618+
declare <type>
26619+
@llvm.experimental.constrained.atan(<type> <op1>,
26620+
metadata <rounding mode>,
26621+
metadata <exception behavior>)
26622+
26623+
Overview:
26624+
"""""""""
26625+
26626+
The '``llvm.experimental.constrained.atan``' intrinsic returns the arctangent of the
26627+
first operand.
26628+
26629+
Arguments:
26630+
""""""""""
26631+
26632+
The first argument and the return type are floating-point numbers of the same
26633+
type.
26634+
26635+
The second and third arguments specify the rounding mode and exception
26636+
behavior as described above.
26637+
26638+
Semantics:
26639+
""""""""""
26640+
26641+
This function returns the arctangent of the specified operand, returning the
26642+
same values as the libm ``atan`` functions would, and handles error
26643+
conditions in the same way.
26644+
26645+
'``llvm.experimental.constrained.sinh``' Intrinsic
26646+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26647+
26648+
Syntax:
26649+
"""""""
26650+
26651+
::
26652+
26653+
declare <type>
26654+
@llvm.experimental.constrained.sinh(<type> <op1>,
26655+
metadata <rounding mode>,
26656+
metadata <exception behavior>)
26657+
26658+
Overview:
26659+
"""""""""
26660+
26661+
The '``llvm.experimental.constrained.sinh``' intrinsic returns the hyperbolic sine of the
26662+
first operand.
26663+
26664+
Arguments:
26665+
""""""""""
26666+
26667+
The first argument and the return type are floating-point numbers of the same
26668+
type.
26669+
26670+
The second and third arguments specify the rounding mode and exception
26671+
behavior as described above.
26672+
26673+
Semantics:
26674+
""""""""""
26675+
26676+
This function returns the hyperbolic sine of the specified operand, returning the
26677+
same values as the libm ``sinh`` functions would, and handles error
26678+
conditions in the same way.
26679+
26680+
26681+
'``llvm.experimental.constrained.cosh``' Intrinsic
26682+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26683+
26684+
Syntax:
26685+
"""""""
26686+
26687+
::
26688+
26689+
declare <type>
26690+
@llvm.experimental.constrained.cosh(<type> <op1>,
26691+
metadata <rounding mode>,
26692+
metadata <exception behavior>)
26693+
26694+
Overview:
26695+
"""""""""
26696+
26697+
The '``llvm.experimental.constrained.cosh``' intrinsic returns the hyperbolic cosine of the
26698+
first operand.
26699+
26700+
Arguments:
26701+
""""""""""
26702+
26703+
The first argument and the return type are floating-point numbers of the same
26704+
type.
26705+
26706+
The second and third arguments specify the rounding mode and exception
26707+
behavior as described above.
26708+
26709+
Semantics:
26710+
""""""""""
26711+
26712+
This function returns the hyperbolic cosine of the specified operand, returning the
26713+
same values as the libm ``cosh`` functions would, and handles error
26714+
conditions in the same way.
26715+
26716+
26717+
'``llvm.experimental.constrained.tanh``' Intrinsic
26718+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26719+
26720+
Syntax:
26721+
"""""""
26722+
26723+
::
26724+
26725+
declare <type>
26726+
@llvm.experimental.constrained.tanh(<type> <op1>,
26727+
metadata <rounding mode>,
26728+
metadata <exception behavior>)
26729+
26730+
Overview:
26731+
"""""""""
26732+
26733+
The '``llvm.experimental.constrained.tanh``' intrinsic returns the hyperbolic tangent of the
26734+
first operand.
26735+
26736+
Arguments:
26737+
""""""""""
26738+
26739+
The first argument and the return type are floating-point numbers of the same
26740+
type.
26741+
26742+
The second and third arguments specify the rounding mode and exception
26743+
behavior as described above.
26744+
26745+
Semantics:
26746+
""""""""""
26747+
26748+
This function returns the hyperbolic tangent of the specified operand, returning the
26749+
same values as the libm ``tanh`` functions would, and handles error
26750+
conditions in the same way.
2653826751

2653926752
'``llvm.experimental.constrained.exp``' Intrinsic
2654026753
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

llvm/include/llvm/CodeGen/BasicTTIImpl.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,6 +1979,24 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
19791979
case Intrinsic::tan:
19801980
ISD = ISD::FTAN;
19811981
break;
1982+
case Intrinsic::asin:
1983+
ISD = ISD::FASIN;
1984+
break;
1985+
case Intrinsic::acos:
1986+
ISD = ISD::FACOS;
1987+
break;
1988+
case Intrinsic::atan:
1989+
ISD = ISD::FATAN;
1990+
break;
1991+
case Intrinsic::sinh:
1992+
ISD = ISD::FSINH;
1993+
break;
1994+
case Intrinsic::cosh:
1995+
ISD = ISD::FCOSH;
1996+
break;
1997+
case Intrinsic::tanh:
1998+
ISD = ISD::FTANH;
1999+
break;
19822000
case Intrinsic::exp:
19832001
ISD = ISD::FEXP;
19842002
break;

llvm/include/llvm/CodeGen/ISDOpcodes.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,12 @@ enum NodeType {
422422
STRICT_FSIN,
423423
STRICT_FCOS,
424424
STRICT_FTAN,
425+
STRICT_FASIN,
426+
STRICT_FACOS,
427+
STRICT_FATAN,
428+
STRICT_FSINH,
429+
STRICT_FCOSH,
430+
STRICT_FTANH,
425431
STRICT_FEXP,
426432
STRICT_FEXP2,
427433
STRICT_FLOG,
@@ -948,6 +954,12 @@ enum NodeType {
948954
FSIN,
949955
FCOS,
950956
FTAN,
957+
FASIN,
958+
FACOS,
959+
FATAN,
960+
FSINH,
961+
FCOSH,
962+
FTANH,
951963
FPOW,
952964
FPOWI,
953965
/// FLDEXP - ldexp, inspired by libm (op0 * 2**op1).

llvm/include/llvm/IR/ConstrainedOps.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,12 @@ CMP_INSTRUCTION(FCmp, 2, 0, experimental_constrained_fcmps, FSETCCS
6969
// Theses are definitions for intrinsic functions, that are converted into
7070
// constrained intrinsics.
7171
//
72+
DAG_FUNCTION(acos, 1, 1, experimental_constrained_acos, FACOS)
73+
DAG_FUNCTION(asin, 1, 1, experimental_constrained_asin, FASIN)
74+
DAG_FUNCTION(atan, 1, 1, experimental_constrained_atan, FATAN)
7275
DAG_FUNCTION(ceil, 1, 0, experimental_constrained_ceil, FCEIL)
7376
DAG_FUNCTION(cos, 1, 1, experimental_constrained_cos, FCOS)
77+
DAG_FUNCTION(cosh, 1, 1, experimental_constrained_cosh, FCOSH)
7478
DAG_FUNCTION(exp, 1, 1, experimental_constrained_exp, FEXP)
7579
DAG_FUNCTION(exp2, 1, 1, experimental_constrained_exp2, FEXP2)
7680
DAG_FUNCTION(floor, 1, 0, experimental_constrained_floor, FFLOOR)
@@ -94,8 +98,10 @@ DAG_FUNCTION(rint, 1, 1, experimental_constrained_rint, FRINT)
9498
DAG_FUNCTION(round, 1, 0, experimental_constrained_round, FROUND)
9599
DAG_FUNCTION(roundeven, 1, 0, experimental_constrained_roundeven, FROUNDEVEN)
96100
DAG_FUNCTION(sin, 1, 1, experimental_constrained_sin, FSIN)
101+
DAG_FUNCTION(sinh, 1, 1, experimental_constrained_sinh, FSINH)
97102
DAG_FUNCTION(sqrt, 1, 1, experimental_constrained_sqrt, FSQRT)
98103
DAG_FUNCTION(tan, 1, 1, experimental_constrained_tan, FTAN)
104+
DAG_FUNCTION(tanh, 1, 1, experimental_constrained_tanh, FTANH)
99105
DAG_FUNCTION(trunc, 1, 0, experimental_constrained_trunc, FTRUNC)
100106

101107
// This is definition for fmuladd intrinsic function, that is converted into

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,18 @@ let IntrProperties = [IntrInaccessibleMemOnly, IntrWillReturn, IntrStrictFP] in
12111211
llvm_anyint_ty,
12121212
llvm_metadata_ty,
12131213
llvm_metadata_ty ]>;
1214+
def int_experimental_constrained_asin : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
1215+
[ LLVMMatchType<0>,
1216+
llvm_metadata_ty,
1217+
llvm_metadata_ty ]>;
1218+
def int_experimental_constrained_acos : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
1219+
[ LLVMMatchType<0>,
1220+
llvm_metadata_ty,
1221+
llvm_metadata_ty ]>;
1222+
def int_experimental_constrained_atan : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
1223+
[ LLVMMatchType<0>,
1224+
llvm_metadata_ty,
1225+
llvm_metadata_ty ]>;
12141226
def int_experimental_constrained_sin : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
12151227
[ LLVMMatchType<0>,
12161228
llvm_metadata_ty,
@@ -1223,6 +1235,18 @@ let IntrProperties = [IntrInaccessibleMemOnly, IntrWillReturn, IntrStrictFP] in
12231235
[ LLVMMatchType<0>,
12241236
llvm_metadata_ty,
12251237
llvm_metadata_ty ]>;
1238+
def int_experimental_constrained_sinh : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
1239+
[ LLVMMatchType<0>,
1240+
llvm_metadata_ty,
1241+
llvm_metadata_ty ]>;
1242+
def int_experimental_constrained_cosh : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
1243+
[ LLVMMatchType<0>,
1244+
llvm_metadata_ty,
1245+
llvm_metadata_ty ]>;
1246+
def int_experimental_constrained_tanh : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
1247+
[ LLVMMatchType<0>,
1248+
llvm_metadata_ty,
1249+
llvm_metadata_ty ]>;
12261250
def int_experimental_constrained_pow : DefaultAttrsIntrinsic<[ llvm_anyfloat_ty ],
12271251
[ LLVMMatchType<0>,
12281252
LLVMMatchType<0>,

llvm/include/llvm/IR/RuntimeLibcalls.def

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,36 @@ HANDLE_LIBCALL(TAN_F64, "tan")
202202
HANDLE_LIBCALL(TAN_F80, "tanl")
203203
HANDLE_LIBCALL(TAN_F128,"tanl")
204204
HANDLE_LIBCALL(TAN_PPCF128, "tanl")
205+
HANDLE_LIBCALL(SINH_F32, "sinhf")
206+
HANDLE_LIBCALL(SINH_F64, "sinh")
207+
HANDLE_LIBCALL(SINH_F80, "sinhl")
208+
HANDLE_LIBCALL(SINH_F128, "sinhl")
209+
HANDLE_LIBCALL(SINH_PPCF128, "sinhl")
210+
HANDLE_LIBCALL(COSH_F32, "coshf")
211+
HANDLE_LIBCALL(COSH_F64, "cosh")
212+
HANDLE_LIBCALL(COSH_F80, "coshl")
213+
HANDLE_LIBCALL(COSH_F128, "coshl")
214+
HANDLE_LIBCALL(COSH_PPCF128, "coshl")
215+
HANDLE_LIBCALL(TANH_F32, "tanhf")
216+
HANDLE_LIBCALL(TANH_F64, "tanh")
217+
HANDLE_LIBCALL(TANH_F80, "tanhl")
218+
HANDLE_LIBCALL(TANH_F128,"tanhl")
219+
HANDLE_LIBCALL(TANH_PPCF128, "tanhl")
220+
HANDLE_LIBCALL(ASIN_F32, "asinf")
221+
HANDLE_LIBCALL(ASIN_F64, "asin")
222+
HANDLE_LIBCALL(ASIN_F80, "asinl")
223+
HANDLE_LIBCALL(ASIN_F128, "asinl")
224+
HANDLE_LIBCALL(ASIN_PPCF128, "asinl")
225+
HANDLE_LIBCALL(ACOS_F32, "acosf")
226+
HANDLE_LIBCALL(ACOS_F64, "acos")
227+
HANDLE_LIBCALL(ACOS_F80, "acosl")
228+
HANDLE_LIBCALL(ACOS_F128, "acosl")
229+
HANDLE_LIBCALL(ACOS_PPCF128, "acosl")
230+
HANDLE_LIBCALL(ATAN_F32, "atanf")
231+
HANDLE_LIBCALL(ATAN_F64, "atan")
232+
HANDLE_LIBCALL(ATAN_F80, "atanl")
233+
HANDLE_LIBCALL(ATAN_F128,"atanl")
234+
HANDLE_LIBCALL(ATAN_PPCF128, "atanl")
205235
HANDLE_LIBCALL(SINCOS_F32, nullptr)
206236
HANDLE_LIBCALL(SINCOS_F64, nullptr)
207237
HANDLE_LIBCALL(SINCOS_F80, nullptr)

llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ def : GINodeEquiv<G_FCEIL, fceil>;
149149
def : GINodeEquiv<G_FCOS, fcos>;
150150
def : GINodeEquiv<G_FSIN, fsin>;
151151
def : GINodeEquiv<G_FTAN, ftan>;
152+
def : GINodeEquiv<G_FACOS, facos>;
153+
def : GINodeEquiv<G_FASIN, fasin>;
154+
def : GINodeEquiv<G_FATAN, fatan>;
155+
def : GINodeEquiv<G_FCOSH, fcosh>;
156+
def : GINodeEquiv<G_FSINH, fsinh>;
157+
def : GINodeEquiv<G_FTANH, ftanh>;
152158
def : GINodeEquiv<G_FABS, fabs>;
153159
def : GINodeEquiv<G_FSQRT, fsqrt>;
154160
def : GINodeEquiv<G_FFLOOR, ffloor>;

0 commit comments

Comments
 (0)