diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 7ecf876e027a9d..02165b0a8aac00 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -15401,6 +15401,228 @@ trapping or setting ``errno``. When specified with the fast-math-flag 'afn', the result may be approximated using a less accurate calculation. +'``llvm.asin.*``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. You can use ``llvm.asin`` on any +floating-point or vector of floating-point type. Not all targets support +all types however. + +:: + + declare float @llvm.asin.f32(float %Val) + declare double @llvm.asin.f64(double %Val) + declare x86_fp80 @llvm.asin.f80(x86_fp80 %Val) + declare fp128 @llvm.asin.f128(fp128 %Val) + declare ppc_fp128 @llvm.asin.ppcf128(ppc_fp128 %Val) + +Overview: +""""""""" + +The '``llvm.asin.*``' intrinsics return the arcsine of the operand. + +Arguments: +"""""""""" + +The argument and return value are floating-point numbers of the same type. + +Semantics: +"""""""""" + +Return the same value as a corresponding libm '``asin``' function but without +trapping or setting ``errno``. + +When specified with the fast-math-flag 'afn', the result may be approximated +using a less accurate calculation. + +'``llvm.acos.*``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. You can use ``llvm.acos`` on any +floating-point or vector of floating-point type. Not all targets support +all types however. + +:: + + declare float @llvm.acos.f32(float %Val) + declare double @llvm.acos.f64(double %Val) + declare x86_fp80 @llvm.acos.f80(x86_fp80 %Val) + declare fp128 @llvm.acos.f128(fp128 %Val) + declare ppc_fp128 @llvm.acos.ppcf128(ppc_fp128 %Val) + +Overview: +""""""""" + +The '``llvm.acos.*``' intrinsics return the arccosine of the operand. + +Arguments: +"""""""""" + +The argument and return value are floating-point numbers of the same type. + +Semantics: +"""""""""" + +Return the same value as a corresponding libm '``acos``' function but without +trapping or setting ``errno``. + +When specified with the fast-math-flag 'afn', the result may be approximated +using a less accurate calculation. + +'``llvm.atan.*``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. You can use ``llvm.atan`` on any +floating-point or vector of floating-point type. Not all targets support +all types however. + +:: + + declare float @llvm.atan.f32(float %Val) + declare double @llvm.atan.f64(double %Val) + declare x86_fp80 @llvm.atan.f80(x86_fp80 %Val) + declare fp128 @llvm.atan.f128(fp128 %Val) + declare ppc_fp128 @llvm.atan.ppcf128(ppc_fp128 %Val) + +Overview: +""""""""" + +The '``llvm.atan.*``' intrinsics return the arctangent of the operand. + +Arguments: +"""""""""" + +The argument and return value are floating-point numbers of the same type. + +Semantics: +"""""""""" + +Return the same value as a corresponding libm '``atan``' function but without +trapping or setting ``errno``. + +When specified with the fast-math-flag 'afn', the result may be approximated +using a less accurate calculation. + +'``llvm.sinh.*``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. You can use ``llvm.sinh`` on any +floating-point or vector of floating-point type. Not all targets support +all types however. + +:: + + declare float @llvm.sinh.f32(float %Val) + declare double @llvm.sinh.f64(double %Val) + declare x86_fp80 @llvm.sinh.f80(x86_fp80 %Val) + declare fp128 @llvm.sinh.f128(fp128 %Val) + declare ppc_fp128 @llvm.sinh.ppcf128(ppc_fp128 %Val) + +Overview: +""""""""" + +The '``llvm.sinh.*``' intrinsics return the hyperbolic sine of the operand. + +Arguments: +"""""""""" + +The argument and return value are floating-point numbers of the same type. + +Semantics: +"""""""""" + +Return the same value as a corresponding libm '``sinh``' function but without +trapping or setting ``errno``. + +When specified with the fast-math-flag 'afn', the result may be approximated +using a less accurate calculation. + +'``llvm.cosh.*``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. You can use ``llvm.cosh`` on any +floating-point or vector of floating-point type. Not all targets support +all types however. + +:: + + declare float @llvm.cosh.f32(float %Val) + declare double @llvm.cosh.f64(double %Val) + declare x86_fp80 @llvm.cosh.f80(x86_fp80 %Val) + declare fp128 @llvm.cosh.f128(fp128 %Val) + declare ppc_fp128 @llvm.cosh.ppcf128(ppc_fp128 %Val) + +Overview: +""""""""" + +The '``llvm.cosh.*``' intrinsics return the hyperbolic cosine of the operand. + +Arguments: +"""""""""" + +The argument and return value are floating-point numbers of the same type. + +Semantics: +"""""""""" + +Return the same value as a corresponding libm '``cosh``' function but without +trapping or setting ``errno``. + +When specified with the fast-math-flag 'afn', the result may be approximated +using a less accurate calculation. + +'``llvm.tanh.*``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. You can use ``llvm.tanh`` on any +floating-point or vector of floating-point type. Not all targets support +all types however. + +:: + + declare float @llvm.tanh.f32(float %Val) + declare double @llvm.tanh.f64(double %Val) + declare x86_fp80 @llvm.tanh.f80(x86_fp80 %Val) + declare fp128 @llvm.tanh.f128(fp128 %Val) + declare ppc_fp128 @llvm.tanh.ppcf128(ppc_fp128 %Val) + +Overview: +""""""""" + +The '``llvm.tanh.*``' intrinsics return the hyperbolic tangent of the operand. + +Arguments: +"""""""""" + +The argument and return value are floating-point numbers of the same type. + +Semantics: +"""""""""" + +Return the same value as a corresponding libm '``tanh``' function but without +trapping or setting ``errno``. + +When specified with the fast-math-flag 'afn', the result may be approximated +using a less accurate calculation. + '``llvm.pow.*``' Intrinsic ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index ef500329d1fb9a..c7d383a5d0c0c1 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -1019,9 +1019,15 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn] in { // environment so they can be treated as readnone. def int_sqrt : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; def int_powi : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_anyint_ty]>; + def int_asin : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; + def int_acos : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; + def int_atan : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; def int_sin : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; def int_cos : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; def int_tan : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; + def int_sinh : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; + def int_cosh : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; + def int_tanh : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; def int_pow : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>]>; def int_log : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; diff --git a/llvm/lib/Target/DirectX/DXIL.td b/llvm/lib/Target/DirectX/DXIL.td index 24a0c8524230c5..adaaa2a6e0d4e1 100644 --- a/llvm/lib/Target/DirectX/DXIL.td +++ b/llvm/lib/Target/DirectX/DXIL.td @@ -269,6 +269,25 @@ def Sin : DXILOpMapping<13, unary, int_sin, def Tan : DXILOpMapping<14, unary, int_tan, "Returns tangent(theta) for theta in radians.", [llvm_halforfloat_ty, LLVMMatchType<0>]>; +def ACos : DXILOpMapping<15, unary, int_acos, + "Returns the arccosine of each component of input.", + [llvm_halforfloat_ty, LLVMMatchType<0>]>; +def ASin : DXILOpMapping<16, unary, int_asin, + "Returns the arcsine of each component of input.", + [llvm_halforfloat_ty, LLVMMatchType<0>]>; +def ATan : DXILOpMapping<17, unary, int_atan, + "Returns the arctangent of each component of input.", + [llvm_halforfloat_ty, LLVMMatchType<0>]>; +def HCos : DXILOpMapping<18, unary, int_cosh, + "Returns the hyperbolic cosine of the specified value.", + [llvm_halforfloat_ty, LLVMMatchType<0>]>; +def HSin : DXILOpMapping<19, unary, int_sinh, + "Returns the hyperbolic sine of the specified value.", + [llvm_halforfloat_ty, LLVMMatchType<0>]>; +def HTan : DXILOpMapping<20, unary, int_tanh, + "Returns the hyperbolic tan of the specified value.", + [llvm_halforfloat_ty, LLVMMatchType<0>]>; + def Exp2 : DXILOpMapping<21, unary, int_exp2, "Returns the base 2 exponential, or 2**x, of the specified value." "exp2(x) = 2**x.", diff --git a/llvm/test/CodeGen/DirectX/acos.ll b/llvm/test/CodeGen/DirectX/acos.ll new file mode 100644 index 00000000000000..31b08833f45a12 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/acos.ll @@ -0,0 +1,20 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for acos are generated for float and half. + +define noundef float @tan_float(float noundef %a) { +entry: +; CHECK:call float @dx.op.unary.f32(i32 15, float %{{.*}}) + %elt.acos = call float @llvm.acos.f32(float %a) + ret float %elt.acos +} + +define noundef half @tan_half(half noundef %a) { +entry: +; CHECK:call half @dx.op.unary.f16(i32 15, half %{{.*}}) + %elt.acos = call half @llvm.acos.f16(half %a) + ret half %elt.acos +} + +declare half @llvm.acos.f16(half) +declare float @llvm.acos.f32(float) diff --git a/llvm/test/CodeGen/DirectX/acos_error.ll b/llvm/test/CodeGen/DirectX/acos_error.ll new file mode 100644 index 00000000000000..e0474e9b758e7e --- /dev/null +++ b/llvm/test/CodeGen/DirectX/acos_error.ll @@ -0,0 +1,10 @@ +; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s + +; DXIL operation acos does not support double overload type +; CHECK: LLVM ERROR: Invalid Overload + +define noundef double @acos_double(double noundef %a) { +entry: + %1 = call double @llvm.acos.f64(double %a) + ret double %1 +} diff --git a/llvm/test/CodeGen/DirectX/asin.ll b/llvm/test/CodeGen/DirectX/asin.ll new file mode 100644 index 00000000000000..56c2d86be3547f --- /dev/null +++ b/llvm/test/CodeGen/DirectX/asin.ll @@ -0,0 +1,20 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for asin are generated for float and half. + +define noundef float @tan_float(float noundef %a) { +entry: +; CHECK:call float @dx.op.unary.f32(i32 16, float %{{.*}}) + %elt.asin = call float @llvm.asin.f32(float %a) + ret float %elt.asin +} + +define noundef half @tan_half(half noundef %a) { +entry: +; CHECK:call half @dx.op.unary.f16(i32 16, half %{{.*}}) + %elt.asin = call half @llvm.asin.f16(half %a) + ret half %elt.asin +} + +declare half @llvm.asin.f16(half) +declare float @llvm.asin.f32(float) diff --git a/llvm/test/CodeGen/DirectX/asin_error.ll b/llvm/test/CodeGen/DirectX/asin_error.ll new file mode 100644 index 00000000000000..ddd4b2e424f62f --- /dev/null +++ b/llvm/test/CodeGen/DirectX/asin_error.ll @@ -0,0 +1,10 @@ +; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s + +; DXIL operation asin does not support double overload type +; CHECK: LLVM ERROR: Invalid Overload + +define noundef double @asin_double(double noundef %a) { +entry: + %1 = call double @llvm.asin.f64(double %a) + ret double %1 +} diff --git a/llvm/test/CodeGen/DirectX/atan.ll b/llvm/test/CodeGen/DirectX/atan.ll new file mode 100644 index 00000000000000..7aa4418a598132 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/atan.ll @@ -0,0 +1,20 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for atan are generated for float and half. + +define noundef float @tan_float(float noundef %a) { +entry: +; CHECK:call float @dx.op.unary.f32(i32 17, float %{{.*}}) + %elt.atan = call float @llvm.atan.f32(float %a) + ret float %elt.atan +} + +define noundef half @tan_half(half noundef %a) { +entry: +; CHECK:call half @dx.op.unary.f16(i32 17, half %{{.*}}) + %elt.atan = call half @llvm.atan.f16(half %a) + ret half %elt.atan +} + +declare half @llvm.atan.f16(half) +declare float @llvm.atan.f32(float) diff --git a/llvm/test/CodeGen/DirectX/atan_error.ll b/llvm/test/CodeGen/DirectX/atan_error.ll new file mode 100644 index 00000000000000..1880b1d38ba3c2 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/atan_error.ll @@ -0,0 +1,10 @@ +; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s + +; DXIL operation atan does not support double overload type +; CHECK: LLVM ERROR: Invalid Overload + +define noundef double @atan_double(double noundef %a) { +entry: + %1 = call double @llvm.atan.f64(double %a) + ret double %1 +} diff --git a/llvm/test/CodeGen/DirectX/cosh.ll b/llvm/test/CodeGen/DirectX/cosh.ll new file mode 100644 index 00000000000000..4fe22f0a38ce1f --- /dev/null +++ b/llvm/test/CodeGen/DirectX/cosh.ll @@ -0,0 +1,20 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for cosh are generated for float and half. + +define noundef float @tan_float(float noundef %a) { +entry: +; CHECK:call float @dx.op.unary.f32(i32 18, float %{{.*}}) + %elt.cosh = call float @llvm.cosh.f32(float %a) + ret float %elt.cosh +} + +define noundef half @tan_half(half noundef %a) { +entry: +; CHECK:call half @dx.op.unary.f16(i32 18, half %{{.*}}) + %elt.cosh = call half @llvm.cosh.f16(half %a) + ret half %elt.cosh +} + +declare half @llvm.cosh.f16(half) +declare float @llvm.cosh.f32(float) diff --git a/llvm/test/CodeGen/DirectX/cosh_error.ll b/llvm/test/CodeGen/DirectX/cosh_error.ll new file mode 100644 index 00000000000000..cf66c54db1a08a --- /dev/null +++ b/llvm/test/CodeGen/DirectX/cosh_error.ll @@ -0,0 +1,10 @@ +; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s + +; DXIL operation cosh does not support double overload type +; CHECK: LLVM ERROR: Invalid Overload + +define noundef double @cosh_double(double noundef %a) { +entry: + %1 = call double @llvm.cosh.f64(double %a) + ret double %1 +} diff --git a/llvm/test/CodeGen/DirectX/sinh.ll b/llvm/test/CodeGen/DirectX/sinh.ll new file mode 100644 index 00000000000000..76d189836f3939 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/sinh.ll @@ -0,0 +1,20 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for sinh are generated for float and half. + +define noundef float @tan_float(float noundef %a) { +entry: +; CHECK:call float @dx.op.unary.f32(i32 19, float %{{.*}}) + %elt.sinh = call float @llvm.sinh.f32(float %a) + ret float %elt.sinh +} + +define noundef half @tan_half(half noundef %a) { +entry: +; CHECK:call half @dx.op.unary.f16(i32 19, half %{{.*}}) + %elt.sinh = call half @llvm.sinh.f16(half %a) + ret half %elt.sinh +} + +declare half @llvm.sinh.f16(half) +declare float @llvm.sinh.f32(float) diff --git a/llvm/test/CodeGen/DirectX/sinh_error.ll b/llvm/test/CodeGen/DirectX/sinh_error.ll new file mode 100644 index 00000000000000..6a021ce88eb3bf --- /dev/null +++ b/llvm/test/CodeGen/DirectX/sinh_error.ll @@ -0,0 +1,10 @@ +; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s + +; DXIL operation sinh does not support double overload type +; CHECK: LLVM ERROR: Invalid Overload + +define noundef double @sinh_double(double noundef %a) { +entry: + %1 = call double @llvm.sinh.f64(double %a) + ret double %1 +} diff --git a/llvm/test/CodeGen/DirectX/tanh.ll b/llvm/test/CodeGen/DirectX/tanh.ll new file mode 100644 index 00000000000000..d0313178c7ac3d --- /dev/null +++ b/llvm/test/CodeGen/DirectX/tanh.ll @@ -0,0 +1,20 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for tanh are generated for float and half. + +define noundef float @tan_float(float noundef %a) { +entry: +; CHECK:call float @dx.op.unary.f32(i32 20, float %{{.*}}) + %elt.tanh = call float @llvm.tanh.f32(float %a) + ret float %elt.tanh +} + +define noundef half @tan_half(half noundef %a) { +entry: +; CHECK:call half @dx.op.unary.f16(i32 20, half %{{.*}}) + %elt.tanh = call half @llvm.tanh.f16(half %a) + ret half %elt.tanh +} + +declare half @llvm.tanh.f16(half) +declare float @llvm.tanh.f32(float) diff --git a/llvm/test/CodeGen/DirectX/tanh_error.ll b/llvm/test/CodeGen/DirectX/tanh_error.ll new file mode 100644 index 00000000000000..a1b8cbf0e13bc4 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/tanh_error.ll @@ -0,0 +1,10 @@ +; RUN: not opt -S -dxil-op-lower %s 2>&1 | FileCheck %s + +; DXIL operation tanh does not support double overload type +; CHECK: LLVM ERROR: Invalid Overload + +define noundef double @tanh_double(double noundef %a) { +entry: + %1 = call double @llvm.tanh.f64(double %a) + ret double %1 +}