Skip to content

Commit 0d08c64

Browse files
committed
[DirectX] Add trig intrinsics and link them with DXIL backend
This change is part of this proposal: https://discourse.llvm.org/t/rfc-all-the-math-intrinsics/78294 This is part 1 of 4 PRs. It sets the ground work for adding the intrinsics. Add DXIL Lower for acos, asin, atan, cosh, sinh, and tanh llvm#70079 llvm#70080 llvm#70081 llvm#70083 llvm#70084 llvm#95966
1 parent b1477eb commit 0d08c64

File tree

15 files changed

+427
-0
lines changed

15 files changed

+427
-0
lines changed

llvm/docs/LangRef.rst

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15384,6 +15384,228 @@ trapping or setting ``errno``.
1538415384
When specified with the fast-math-flag 'afn', the result may be approximated
1538515385
using a less accurate calculation.
1538615386

15387+
'``llvm.asin.*``' Intrinsic
15388+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
15389+
15390+
Syntax:
15391+
"""""""
15392+
15393+
This is an overloaded intrinsic. You can use ``llvm.asin`` on any
15394+
floating-point or vector of floating-point type. Not all targets support
15395+
all types however.
15396+
15397+
::
15398+
15399+
declare float @llvm.asin.f32(float %Val)
15400+
declare double @llvm.asin.f64(double %Val)
15401+
declare x86_fp80 @llvm.asin.f80(x86_fp80 %Val)
15402+
declare fp128 @llvm.asin.f128(fp128 %Val)
15403+
declare ppc_fp128 @llvm.asin.ppcf128(ppc_fp128 %Val)
15404+
15405+
Overview:
15406+
"""""""""
15407+
15408+
The '``llvm.asin.*``' intrinsics return the arcsine of the operand.
15409+
15410+
Arguments:
15411+
""""""""""
15412+
15413+
The argument and return value are floating-point numbers of the same type.
15414+
15415+
Semantics:
15416+
""""""""""
15417+
15418+
Return the same value as a corresponding libm '``asin``' function but without
15419+
trapping or setting ``errno``.
15420+
15421+
When specified with the fast-math-flag 'afn', the result may be approximated
15422+
using a less accurate calculation.
15423+
15424+
'``llvm.acos.*``' Intrinsic
15425+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
15426+
15427+
Syntax:
15428+
"""""""
15429+
15430+
This is an overloaded intrinsic. You can use ``llvm.acos`` on any
15431+
floating-point or vector of floating-point type. Not all targets support
15432+
all types however.
15433+
15434+
::
15435+
15436+
declare float @llvm.acos.f32(float %Val)
15437+
declare double @llvm.acos.f64(double %Val)
15438+
declare x86_fp80 @llvm.acos.f80(x86_fp80 %Val)
15439+
declare fp128 @llvm.acos.f128(fp128 %Val)
15440+
declare ppc_fp128 @llvm.acos.ppcf128(ppc_fp128 %Val)
15441+
15442+
Overview:
15443+
"""""""""
15444+
15445+
The '``llvm.acos.*``' intrinsics return the arccosine of the operand.
15446+
15447+
Arguments:
15448+
""""""""""
15449+
15450+
The argument and return value are floating-point numbers of the same type.
15451+
15452+
Semantics:
15453+
""""""""""
15454+
15455+
Return the same value as a corresponding libm '``acos``' function but without
15456+
trapping or setting ``errno``.
15457+
15458+
When specified with the fast-math-flag 'afn', the result may be approximated
15459+
using a less accurate calculation.
15460+
15461+
'``llvm.atan.*``' Intrinsic
15462+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
15463+
15464+
Syntax:
15465+
"""""""
15466+
15467+
This is an overloaded intrinsic. You can use ``llvm.atan`` on any
15468+
floating-point or vector of floating-point type. Not all targets support
15469+
all types however.
15470+
15471+
::
15472+
15473+
declare float @llvm.atan.f32(float %Val)
15474+
declare double @llvm.atan.f64(double %Val)
15475+
declare x86_fp80 @llvm.atan.f80(x86_fp80 %Val)
15476+
declare fp128 @llvm.atan.f128(fp128 %Val)
15477+
declare ppc_fp128 @llvm.atan.ppcf128(ppc_fp128 %Val)
15478+
15479+
Overview:
15480+
"""""""""
15481+
15482+
The '``llvm.atan.*``' intrinsics return the arctangent of the operand.
15483+
15484+
Arguments:
15485+
""""""""""
15486+
15487+
The argument and return value are floating-point numbers of the same type.
15488+
15489+
Semantics:
15490+
""""""""""
15491+
15492+
Return the same value as a corresponding libm '``atan``' function but without
15493+
trapping or setting ``errno``.
15494+
15495+
When specified with the fast-math-flag 'afn', the result may be approximated
15496+
using a less accurate calculation.
15497+
15498+
'``llvm.sinh.*``' Intrinsic
15499+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
15500+
15501+
Syntax:
15502+
"""""""
15503+
15504+
This is an overloaded intrinsic. You can use ``llvm.sinh`` on any
15505+
floating-point or vector of floating-point type. Not all targets support
15506+
all types however.
15507+
15508+
::
15509+
15510+
declare float @llvm.sinh.f32(float %Val)
15511+
declare double @llvm.sinh.f64(double %Val)
15512+
declare x86_fp80 @llvm.sinh.f80(x86_fp80 %Val)
15513+
declare fp128 @llvm.sinh.f128(fp128 %Val)
15514+
declare ppc_fp128 @llvm.sinh.ppcf128(ppc_fp128 %Val)
15515+
15516+
Overview:
15517+
"""""""""
15518+
15519+
The '``llvm.sinh.*``' intrinsics return the hyperbolic sine of the operand.
15520+
15521+
Arguments:
15522+
""""""""""
15523+
15524+
The argument and return value are floating-point numbers of the same type.
15525+
15526+
Semantics:
15527+
""""""""""
15528+
15529+
Return the same value as a corresponding libm '``sinh``' function but without
15530+
trapping or setting ``errno``.
15531+
15532+
When specified with the fast-math-flag 'afn', the result may be approximated
15533+
using a less accurate calculation.
15534+
15535+
'``llvm.cosh.*``' Intrinsic
15536+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
15537+
15538+
Syntax:
15539+
"""""""
15540+
15541+
This is an overloaded intrinsic. You can use ``llvm.cosh`` on any
15542+
floating-point or vector of floating-point type. Not all targets support
15543+
all types however.
15544+
15545+
::
15546+
15547+
declare float @llvm.cosh.f32(float %Val)
15548+
declare double @llvm.cosh.f64(double %Val)
15549+
declare x86_fp80 @llvm.cosh.f80(x86_fp80 %Val)
15550+
declare fp128 @llvm.cosh.f128(fp128 %Val)
15551+
declare ppc_fp128 @llvm.cosh.ppcf128(ppc_fp128 %Val)
15552+
15553+
Overview:
15554+
"""""""""
15555+
15556+
The '``llvm.cosh.*``' intrinsics return the hyperbolic cosine of the operand.
15557+
15558+
Arguments:
15559+
""""""""""
15560+
15561+
The argument and return value are floating-point numbers of the same type.
15562+
15563+
Semantics:
15564+
""""""""""
15565+
15566+
Return the same value as a corresponding libm '``cosh``' function but without
15567+
trapping or setting ``errno``.
15568+
15569+
When specified with the fast-math-flag 'afn', the result may be approximated
15570+
using a less accurate calculation.
15571+
15572+
'``llvm.tanh.*``' Intrinsic
15573+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
15574+
15575+
Syntax:
15576+
"""""""
15577+
15578+
This is an overloaded intrinsic. You can use ``llvm.tanh`` on any
15579+
floating-point or vector of floating-point type. Not all targets support
15580+
all types however.
15581+
15582+
::
15583+
15584+
declare float @llvm.tanh.f32(float %Val)
15585+
declare double @llvm.tanh.f64(double %Val)
15586+
declare x86_fp80 @llvm.tanh.f80(x86_fp80 %Val)
15587+
declare fp128 @llvm.tanh.f128(fp128 %Val)
15588+
declare ppc_fp128 @llvm.tanh.ppcf128(ppc_fp128 %Val)
15589+
15590+
Overview:
15591+
"""""""""
15592+
15593+
The '``llvm.tanh.*``' intrinsics return the hyperbolic tangent of the operand.
15594+
15595+
Arguments:
15596+
""""""""""
15597+
15598+
The argument and return value are floating-point numbers of the same type.
15599+
15600+
Semantics:
15601+
""""""""""
15602+
15603+
Return the same value as a corresponding libm '``tanh``' function but without
15604+
trapping or setting ``errno``.
15605+
15606+
When specified with the fast-math-flag 'afn', the result may be approximated
15607+
using a less accurate calculation.
15608+
1538715609
'``llvm.pow.*``' Intrinsic
1538815610
^^^^^^^^^^^^^^^^^^^^^^^^^^
1538915611

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,9 +1019,15 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn] in {
10191019
// environment so they can be treated as readnone.
10201020
def int_sqrt : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
10211021
def int_powi : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_anyint_ty]>;
1022+
def int_asin : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
1023+
def int_acos : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
1024+
def int_atan : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
10221025
def int_sin : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
10231026
def int_cos : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
10241027
def int_tan : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
1028+
def int_sinh : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
1029+
def int_cosh : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
1030+
def int_tanh : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
10251031
def int_pow : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
10261032
[LLVMMatchType<0>, LLVMMatchType<0>]>;
10271033
def int_log : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;

llvm/lib/Target/DirectX/DXIL.td

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,25 @@ def Sin : DXILOpMapping<13, unary, int_sin,
269269
def Tan : DXILOpMapping<14, unary, int_tan,
270270
"Returns tangent(theta) for theta in radians.",
271271
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
272+
def ACos : DXILOpMapping<15, unary, int_acos,
273+
"Returns the arccosine of each component of input.",
274+
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
275+
def ASin : DXILOpMapping<16, unary, int_asin,
276+
"Returns the arcsine of each component of input.",
277+
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
278+
def ATan : DXILOpMapping<17, unary, int_atan,
279+
"Returns the arctangent of each component of input.",
280+
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
281+
def HCos : DXILOpMapping<18, unary, int_cosh,
282+
"Returns the hyperbolic cosine of the specified value.",
283+
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
284+
def HSin : DXILOpMapping<19, unary, int_sinh,
285+
"Returns the hyperbolic sine of the specified value.",
286+
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
287+
def HTan : DXILOpMapping<20, unary, int_tanh,
288+
"Returns the hyperbolic tan of the specified value.",
289+
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
290+
272291
def Exp2 : DXILOpMapping<21, unary, int_exp2,
273292
"Returns the base 2 exponential, or 2**x, of the specified value."
274293
"exp2(x) = 2**x.",

llvm/test/CodeGen/DirectX/acos.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: opt -S -dxil-op-lower < %s | FileCheck %s
2+
3+
; Make sure dxil operation function calls for acos are generated for float and half.
4+
5+
define noundef float @tan_float(float noundef %a) {
6+
entry:
7+
; CHECK:call float @dx.op.unary.f32(i32 15, float %{{.*}})
8+
%elt.acos = call float @llvm.acos.f32(float %a)
9+
ret float %elt.acos
10+
}
11+
12+
define noundef half @tan_half(half noundef %a) {
13+
entry:
14+
; CHECK:call half @dx.op.unary.f16(i32 15, half %{{.*}})
15+
%elt.acos = call half @llvm.acos.f16(half %a)
16+
ret half %elt.acos
17+
}
18+
19+
declare half @llvm.acos.f16(half)
20+
declare float @llvm.acos.f32(float)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s
2+
3+
; DXIL operation acos does not support double overload type
4+
; CHECK: LLVM ERROR: Invalid Overload
5+
6+
define noundef double @acos_double(double noundef %a) {
7+
entry:
8+
%1 = call double @llvm.acos.f64(double %a)
9+
ret double %1
10+
}

llvm/test/CodeGen/DirectX/asin.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: opt -S -dxil-op-lower < %s | FileCheck %s
2+
3+
; Make sure dxil operation function calls for asin are generated for float and half.
4+
5+
define noundef float @tan_float(float noundef %a) {
6+
entry:
7+
; CHECK:call float @dx.op.unary.f32(i32 16, float %{{.*}})
8+
%elt.asin = call float @llvm.asin.f32(float %a)
9+
ret float %elt.asin
10+
}
11+
12+
define noundef half @tan_half(half noundef %a) {
13+
entry:
14+
; CHECK:call half @dx.op.unary.f16(i32 16, half %{{.*}})
15+
%elt.asin = call half @llvm.asin.f16(half %a)
16+
ret half %elt.asin
17+
}
18+
19+
declare half @llvm.asin.f16(half)
20+
declare float @llvm.asin.f32(float)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s
2+
3+
; DXIL operation asin does not support double overload type
4+
; CHECK: LLVM ERROR: Invalid Overload
5+
6+
define noundef double @asin_double(double noundef %a) {
7+
entry:
8+
%1 = call double @llvm.asin.f64(double %a)
9+
ret double %1
10+
}

llvm/test/CodeGen/DirectX/atan.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: opt -S -dxil-op-lower < %s | FileCheck %s
2+
3+
; Make sure dxil operation function calls for atan are generated for float and half.
4+
5+
define noundef float @tan_float(float noundef %a) {
6+
entry:
7+
; CHECK:call float @dx.op.unary.f32(i32 17, float %{{.*}})
8+
%elt.atan = call float @llvm.atan.f32(float %a)
9+
ret float %elt.atan
10+
}
11+
12+
define noundef half @tan_half(half noundef %a) {
13+
entry:
14+
; CHECK:call half @dx.op.unary.f16(i32 17, half %{{.*}})
15+
%elt.atan = call half @llvm.atan.f16(half %a)
16+
ret half %elt.atan
17+
}
18+
19+
declare half @llvm.atan.f16(half)
20+
declare float @llvm.atan.f32(float)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s
2+
3+
; DXIL operation atan does not support double overload type
4+
; CHECK: LLVM ERROR: Invalid Overload
5+
6+
define noundef double @atan_double(double noundef %a) {
7+
entry:
8+
%1 = call double @llvm.atan.f64(double %a)
9+
ret double %1
10+
}

llvm/test/CodeGen/DirectX/cosh.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; RUN: opt -S -dxil-op-lower < %s | FileCheck %s
2+
3+
; Make sure dxil operation function calls for cosh are generated for float and half.
4+
5+
define noundef float @tan_float(float noundef %a) {
6+
entry:
7+
; CHECK:call float @dx.op.unary.f32(i32 18, float %{{.*}})
8+
%elt.cosh = call float @llvm.cosh.f32(float %a)
9+
ret float %elt.cosh
10+
}
11+
12+
define noundef half @tan_half(half noundef %a) {
13+
entry:
14+
; CHECK:call half @dx.op.unary.f16(i32 18, half %{{.*}})
15+
%elt.cosh = call half @llvm.cosh.f16(half %a)
16+
ret half %elt.cosh
17+
}
18+
19+
declare half @llvm.cosh.f16(half)
20+
declare float @llvm.cosh.f32(float)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s
2+
3+
; DXIL operation cosh does not support double overload type
4+
; CHECK: LLVM ERROR: Invalid Overload
5+
6+
define noundef double @cosh_double(double noundef %a) {
7+
entry:
8+
%1 = call double @llvm.cosh.f64(double %a)
9+
ret double %1
10+
}

0 commit comments

Comments
 (0)