libclc: Update trigpi functions (#187579) These were originally ported from rocm device libs in bc81ebefb7d9d9d71d20bfee2ce4cccb09701e9b. Merge in more recent changes. GitOrigin-RevId: 421bf13e4bf1c19a0cc48fbb0af63b902d3118b1
diff --git a/clc/include/clc/math/clc_sincos_helpers_decl.inc b/clc/include/clc/math/clc_sincos_helpers_decl.inc index 0ef32d0..eff4576 100644 --- a/clc/include/clc/math/clc_sincos_helpers_decl.inc +++ b/clc/include/clc/math/clc_sincos_helpers_decl.inc
@@ -15,6 +15,9 @@ _CLC_DECL _CLC_OVERLOAD _CLC_CONST __CLC_SINCOS_RET_GENTYPE __clc_sincos_reduced_eval(__CLC_FLOATN x); +_CLC_DECL _CLC_OVERLOAD _CLC_CONST __CLC_SINCOS_RET_GENTYPE +__clc_sincospi_reduced_eval(__CLC_FLOATN x); + _CLC_DECL _CLC_OVERLOAD __CLC_FLOATN __clc_sinf_piby4(__CLC_FLOATN x, __CLC_FLOATN y); _CLC_DECL _CLC_OVERLOAD __CLC_FLOATN __clc_cosf_piby4(__CLC_FLOATN x,
diff --git a/clc/include/clc/math/clc_sincos_helpers_fp16_decl.inc b/clc/include/clc/math/clc_sincos_helpers_fp16_decl.inc index a490097..8e2fb9b 100644 --- a/clc/include/clc/math/clc_sincos_helpers_fp16_decl.inc +++ b/clc/include/clc/math/clc_sincos_helpers_fp16_decl.inc
@@ -15,5 +15,8 @@ _CLC_DEF _CLC_OVERLOAD __CLC_SINCOS_RET_GENTYPE __clc_sincos_reduced_eval(__CLC_HALFN x); +_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_SINCOS_RET_GENTYPE +__clc_sincospi_reduced_eval(__CLC_HALFN x); + _CLC_DEF _CLC_OVERLOAD __CLC_INTN __clc_argReductionS(private __CLC_HALFN *r, __CLC_HALFN x);
diff --git a/clc/include/clc/math/clc_sincos_helpers_fp64_decl.inc b/clc/include/clc/math/clc_sincos_helpers_fp64_decl.inc index bbae56c..22081d9 100644 --- a/clc/include/clc/math/clc_sincos_helpers_fp64_decl.inc +++ b/clc/include/clc/math/clc_sincos_helpers_fp64_decl.inc
@@ -15,19 +15,13 @@ _CLC_DEF _CLC_OVERLOAD __CLC_SINCOS_RET_GENTYPE __clc_sincos_reduced_eval(__CLC_DOUBLEN x, __CLC_DOUBLEN y); +_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_SINCOS_RET_GENTYPE +__clc_sincospi_reduced_eval(__CLC_DOUBLEN x); + _CLC_DEF _CLC_OVERLOAD __CLC_DOUBLEN __clc_tan_reduced_eval(__CLC_DOUBLEN x, __CLC_DOUBLEN y, __CLC_INTN is_odd); -_CLC_DECL _CLC_OVERLOAD void __clc_sincos_piby4(__CLC_DOUBLEN x, - __CLC_DOUBLEN xx, - private __CLC_DOUBLEN *sinval, - private __CLC_DOUBLEN *cosval); - -_CLC_DECL _CLC_OVERLOAD void __clc_tan_piby4(__CLC_DOUBLEN x, __CLC_DOUBLEN xx, - private __CLC_DOUBLEN *leadval, - private __CLC_DOUBLEN *tailval); - _CLC_DECL _CLC_OVERLOAD __CLC_INTN __clc_remainder_piby2_small( __CLC_DOUBLEN x, private __CLC_DOUBLEN *r, private __CLC_DOUBLEN *rr);
diff --git a/clc/include/clc/math/clc_sincospi.h b/clc/include/clc/math/clc_sincospi.h new file mode 100644 index 0000000..2b20e0b --- /dev/null +++ b/clc/include/clc/math/clc_sincospi.h
@@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef __CLC_MATH_CLC_SINCOSPI_H__ +#define __CLC_MATH_CLC_SINCOSPI_H__ + +#include "clc/internal/clc.h" + +#define __CLC_BODY "clc/math/unary_decl_with_ptr.inc" +#define __CLC_FUNCTION __clc_sincospi + +#include "clc/math/gentype.inc" + +#undef __CLC_FUNCTION + +#endif // __CLC_MATH_CLC_SINCOSPI_H__
diff --git a/clc/include/clc/math/clc_trigpi_helpers.h b/clc/include/clc/math/clc_trigpi_helpers.h new file mode 100644 index 0000000..b6f4013 --- /dev/null +++ b/clc/include/clc/math/clc_trigpi_helpers.h
@@ -0,0 +1,17 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef __CLC_MATH_CLC_TRIGPI_HELPERS_H__ +#define __CLC_MATH_CLC_TRIGPI_HELPERS_H__ + +#include "clc/internal/clc.h" + +#define __CLC_BODY "clc/math/clc_trigpi_helpers_decl.inc" +#include "clc/math/gentype.inc" + +#endif // __CLC_MATH_CLC_TRIGPI_HELPERS_H__
diff --git a/clc/include/clc/math/clc_trigpi_helpers_decl.inc b/clc/include/clc/math/clc_trigpi_helpers_decl.inc new file mode 100644 index 0000000..1eb5df1 --- /dev/null +++ b/clc/include/clc/math/clc_trigpi_helpers_decl.inc
@@ -0,0 +1,10 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +_CLC_DECL _CLC_OVERLOAD __CLC_INTN +__clc_piArgReductionS(private __CLC_GENTYPE *r, __CLC_GENTYPE x);
diff --git a/clc/include/clc/math/gentype.inc b/clc/include/clc/math/gentype.inc index f36a5b1..6d83b06 100644 --- a/clc/include/clc/math/gentype.inc +++ b/clc/include/clc/math/gentype.inc
@@ -69,6 +69,9 @@ #define __CLC_CONVERT_S_GENTYPE __CLC_XCONCAT(__clc_convert_, __CLC_S_GENTYPE) #define __CLC_CONVERT_U_GENTYPE __CLC_XCONCAT(__clc_convert_, __CLC_U_GENTYPE) +#define __CLC_GENTYPE_S_SIGNBIT (__CLC_S_GENTYPE)((1ll << (__CLC_FPSIZE - 1))) +#define __CLC_GENTYPE_U_SIGNBIT (__CLC_U_GENTYPE)((1ull << (__CLC_FPSIZE - 1u))) + #if (!defined(__CLC_HALF_ONLY) && !defined(__CLC_DOUBLE_ONLY)) #define __CLC_SCALAR_GENTYPE float #define __CLC_FPSIZE 32
diff --git a/clc/lib/generic/CMakeLists.txt b/clc/lib/generic/CMakeLists.txt index 9f93fdb..8c5e73c 100644 --- a/clc/lib/generic/CMakeLists.txt +++ b/clc/lib/generic/CMakeLists.txt
@@ -156,6 +156,7 @@ math/clc_rsqrt.cl math/clc_sin.cl math/clc_sincos.cl + math/clc_sincospi.cl math/clc_sincos_helpers.cl math/clc_sinh.cl math/clc_sinpi.cl @@ -167,6 +168,7 @@ math/clc_tanh.cl math/clc_tanpi.cl math/clc_tgamma.cl + math/clc_trigpi_helpers.cl math/clc_trunc.cl mem_fence/clc_mem_fence.cl misc/clc_shuffle.cl
diff --git a/clc/lib/generic/math/clc_cospi.cl b/clc/lib/generic/math/clc_cospi.cl index 7ccaae3..66efdb2 100644 --- a/clc/lib/generic/math/clc_cospi.cl +++ b/clc/lib/generic/math/clc_cospi.cl
@@ -6,12 +6,8 @@ // //===----------------------------------------------------------------------===// -#include "clc/clc_convert.h" -#include "clc/float/definitions.h" -#include "clc/internal/clc.h" -#include "clc/math/clc_fabs.h" -#include "clc/math/clc_sincos_helpers.h" -#include "clc/math/math.h" +#include "clc/math/clc_cospi.h" +#include "clc/math/clc_sincospi.h" #define __CLC_BODY "clc_cospi.inc" #include "clc/math/gentype.inc"
diff --git a/clc/lib/generic/math/clc_cospi.inc b/clc/lib/generic/math/clc_cospi.inc index b037f82..c5f5d7c 100644 --- a/clc/lib/generic/math/clc_cospi.inc +++ b/clc/lib/generic/math/clc_cospi.inc
@@ -6,111 +6,8 @@ // //===----------------------------------------------------------------------===// -#if __CLC_FPSIZE == 32 - _CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_cospi(__CLC_GENTYPE x) { - __CLC_GENTYPE absx = __clc_fabs(x); - __CLC_INTN ix = __CLC_AS_INTN(absx); - __CLC_INTN iax = __CLC_CONVERT_INTN(absx); - __CLC_GENTYPE r = absx - __CLC_CONVERT_GENTYPE(iax); - __CLC_INTN xodd = (iax & 0x1) != 0 ? (__CLC_INTN)0x80000000 : (__CLC_INTN)0; - - // Initialize with return for +-Inf and NaN - __CLC_INTN ir = QNANBITPATT_SP32; - - // 2^24 <= |x| < Inf, the result is always even integer - ir = ix < PINFBITPATT_SP32 ? 0x3f800000 : ir; - - // 2^23 <= |x| < 2^24, the result is always integer - ir = ix < 0x4b800000 ? xodd | 0x3f800000 : ir; - - // 0x1.0p-7 <= |x| < 2^23, result depends on which 0.25 interval - - // r < 1.0 - __CLC_GENTYPE a = 1.0f - r; - __CLC_INTN e = 1; - __CLC_INTN s = xodd ^ (__CLC_INTN)0x80000000; - - // r <= 0.75 - __CLC_INTN c = r <= 0.75f; - a = c ? r - 0.5f : a; - e = c ? 0 : e; - - // r < 0.5 - c = r < 0.5f; - a = c ? 0.5f - r : a; - s = c ? xodd : s; - - // r <= 0.25 - c = r <= 0.25f; - a = c ? r : a; - e = c ? 1 : e; - - __CLC_GENTYPE sinval, cosval; - __clc_sincos_piby4(a * M_PI_F, &sinval, &cosval); - __CLC_INTN jr = s ^ __CLC_AS_INTN(e != 0 ? cosval : sinval); - - ir = ix < 0x4b000000 ? jr : ir; - - return __CLC_AS_GENTYPE(ir); + __CLC_GENTYPE cos; + (void)__clc_sincospi(x, &cos); + return cos; } - -#elif __CLC_FPSIZE == 64 - -_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_cospi(__CLC_GENTYPE x) { - __CLC_GENTYPE absx = __clc_fabs(x); - __CLC_LONGN ix = __CLC_AS_LONGN(absx); - __CLC_LONGN iax = __CLC_CONVERT_LONGN(absx); - __CLC_GENTYPE r = absx - __CLC_CONVERT_GENTYPE(iax); - __CLC_LONGN xodd = - (iax & 0x1L) != 0 ? (__CLC_LONGN)0x8000000000000000L : (__CLC_LONGN)0L; - - // Initialize with return for +-Inf and NaN - __CLC_LONGN ir = QNANBITPATT_DP64; - - // 2^53 <= |x| < Inf, the result is always even integer - ir = ix < PINFBITPATT_DP64 ? 0x3ff0000000000000L : ir; - - // 2^52 <= |x| < 2^53, the result is always integer - ir = absx < 0x1.0p+53 ? xodd | 0x3ff0000000000000L : ir; - - // 0x1.0p-7 <= |x| < 2^52, result depends on which 0.25 interval - - // r < 1.0 - __CLC_GENTYPE a = 1.0 - r; - __CLC_LONGN e = 1; - __CLC_LONGN s = xodd ^ (__CLC_LONGN)0x8000000000000000L; - - // r <= 0.75 - __CLC_LONGN c = r <= 0.75; - __CLC_GENTYPE t = r - 0.5; - a = c ? t : a; - e = c ? 0 : e; - - // r < 0.5 - c = r < 0.5; - t = 0.5 - r; - a = c ? t : a; - s = c ? xodd : s; - - // r <= 0.25 - c = r <= 0.25; - a = c ? r : a; - e = c ? 1 : e; - - __CLC_GENTYPE sinval, cosval; - __clc_sincos_piby4(a * M_PI, 0.0, &sinval, &cosval); - __CLC_LONGN jr = s ^ __CLC_AS_LONGN(e != 0 ? cosval : sinval); - - ir = absx < 0x1.0p+52 ? jr : ir; - - return __CLC_AS_GENTYPE(ir); -} - -#elif __CLC_FPSIZE == 16 - -_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_cospi(__CLC_GENTYPE x) { - return __CLC_CONVERT_GENTYPE(__clc_cospi(__CLC_CONVERT_FLOATN(x))); -} - -#endif
diff --git a/clc/lib/generic/math/clc_sincos_helpers.inc b/clc/lib/generic/math/clc_sincos_helpers.inc index 21dedce..2603f9f 100644 --- a/clc/lib/generic/math/clc_sincos_helpers.inc +++ b/clc/lib/generic/math/clc_sincos_helpers.inc
@@ -41,6 +41,33 @@ return ret; } +_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_SINCOS_RET_GENTYPE +__clc_sincospi_reduced_eval(__CLC_GENTYPE x) { + __CLC_GENTYPE t = x * x; + + __CLC_GENTYPE sx = + __clc_mad(t, + __clc_mad(t, __clc_mad(t, 0x1.eb5482p-3f, -0x1.3e497cp-1f), + 0x1.468e6cp+1f), + -0x1.4abc1cp+2f); + sx = x * t * sx; + sx = __clc_mad(x, 0x1.921fb6p+1f, sx); + + __CLC_GENTYPE cx = __clc_mad( + t, + __clc_mad(t, + __clc_mad(t, __clc_mad(t, 0x1.97ca88p-5f, 0x1.c85d3ap-3f), + -0x1.55a3b4p+0f), + 0x1.03c1a6p+2f), + -0x1.3bd3ccp+2f); + cx = __clc_mad(t, cx, 1.0f); + + __CLC_SINCOS_RET_GENTYPE ret; + ret.cos = cx; + ret.sin = sx; + return ret; +} + // Evaluate single precisions sin and cos of value in interval [-pi/4, pi/4] _CLC_DEF _CLC_OVERLOAD void __clc_sincos_piby4(__CLC_FLOATN x, private __CLC_FLOATN *sinval,
diff --git a/clc/lib/generic/math/clc_sincos_helpers_fp16.inc b/clc/lib/generic/math/clc_sincos_helpers_fp16.inc index 31ba31b..5d64613 100644 --- a/clc/lib/generic/math/clc_sincos_helpers_fp16.inc +++ b/clc/lib/generic/math/clc_sincos_helpers_fp16.inc
@@ -34,3 +34,19 @@ ret.sin = __clc_mad(x, t * __clc_mad(t, 0x1.0bp-7h, -0x1.554p-3h), x); return ret; } + +_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_SINCOS_RET_GENTYPE +__clc_sincospi_reduced_eval(__CLC_HALFN x) { + __CLC_HALFN t = x * x; + __CLC_HALFN sx = __clc_mad(t, 0x1.b84p+0h, -0x1.46cp+2h); + sx = x * t * sx; + sx = __clc_mad(x, 0x1.92p+1h, sx); + + __CLC_HALFN cx = __clc_mad(t, 0x1.fbp+1h, -0x1.3bcp+2h); + cx = __clc_mad(t, cx, 1.0h); + + __CLC_SINCOS_RET_GENTYPE ret; + ret.cos = cx; + ret.sin = sx; + return ret; +}
diff --git a/clc/lib/generic/math/clc_sincos_helpers_fp64.inc b/clc/lib/generic/math/clc_sincos_helpers_fp64.inc index cdb947c..059ac8a 100644 --- a/clc/lib/generic/math/clc_sincos_helpers_fp64.inc +++ b/clc/lib/generic/math/clc_sincos_helpers_fp64.inc
@@ -41,6 +41,29 @@ return ret; } +_CLC_DEF _CLC_OVERLOAD __CLC_SINCOS_RET_GENTYPE +__clc_sincospi_reduced_eval(__CLC_GENTYPE x) { + __CLC_GENTYPE t = x * x; + + __CLC_GENTYPE sx = __clc_mad(t, __clc_mad(t, __clc_mad(t, __clc_mad(t, + __clc_mad(t, + 0x1.e357ef99eb0bbp-12, -0x1.e2fe76fdffd2bp-8), 0x1.50782d5f14825p-4), -0x1.32d2ccdfe9424p-1), + 0x1.466bc67754fffp+1), -0x1.4abbce625be09p+2); + sx = x * t * sx; + sx = __clc_mad(x, 0x1.921fb54442d18p+1, sx); + + __CLC_GENTYPE cx = __clc_mad(t, __clc_mad(t, __clc_mad(t, __clc_mad(t, + __clc_mad(t, __clc_mad(t, + -0x1.b167302e21c33p-14, 0x1.f9c89ca1d4f33p-10), -0x1.a6d1e7294bff9p-6), 0x1.e1f5067b90b37p-3), + -0x1.55d3c7e3c325bp+0), 0x1.03c1f081b5a67p+2), -0x1.3bd3cc9be45dep+2); + cx = __clc_mad(t, cx, 1.0); + + __CLC_SINCOS_RET_GENTYPE ret; + ret.cos = cx; + ret.sin = sx; + return ret; +} + _CLC_DEF _CLC_OVERLOAD __CLC_DOUBLEN __clc_tan_reduced_eval(__CLC_DOUBLEN x, __CLC_DOUBLEN xx, __CLC_INTN is_odd) { @@ -123,68 +146,6 @@ *cosval = cp; } -_CLC_DEF _CLC_OVERLOAD void __clc_tan_piby4(__CLC_DOUBLEN x, __CLC_DOUBLEN xx, - private __CLC_DOUBLEN *leadval, - private __CLC_DOUBLEN *tailval) { - // 0x3fe921fb54442d18 - const __CLC_DOUBLEN piby4_lead = 7.85398163397448278999e-01; - // 0x3c81a62633145c06 - const __CLC_DOUBLEN piby4_tail = 3.06161699786838240164e-17; - - // In order to maintain relative precision transform using the identity: - // tan(pi/4-x) = (1-tan(x))/(1+tan(x)) for arguments close to pi/4. - // Similarly use tan(x-pi/4) = (tan(x)-1)/(tan(x)+1) close to -pi/4. - - __CLC_LONGN ca = x > 0.68; - __CLC_LONGN cb = x < -0.68; - __CLC_DOUBLEN transform = ca ? 1.0 : 0.0; - transform = cb ? -1.0 : transform; - - __CLC_DOUBLEN tx = __clc_fma(-transform, x, piby4_lead) + - __clc_fma(-transform, xx, piby4_tail); - __CLC_LONGN c = ca | cb; - x = c ? tx : x; - xx = c ? 0.0 : xx; - - // Core Remez [2,3] approximation to tan(x+xx) on the interval [0,0.68]. - __CLC_DOUBLEN t1 = x; - __CLC_DOUBLEN r = __clc_fma(2.0, x * xx, x * x); - - __CLC_DOUBLEN a = __clc_fma(r, - __clc_fma(r, 0.224044448537022097264602535574e-3, - -0.229345080057565662883358588111e-1), - 0.372379159759792203640806338901e0); - - __CLC_DOUBLEN b = - __clc_fma(r, - __clc_fma(r, - __clc_fma(r, -0.232371494088563558304549252913e-3, - 0.260656620398645407524064091208e-1), - -0.515658515729031149329237816945e0), - 0.111713747927937668539901657944e1); - - __CLC_DOUBLEN t2 = __clc_fma(MATH_DIVIDE(a, b), x * r, xx); - - __CLC_DOUBLEN tp = t1 + t2; - - // Compute -1.0/(t1 + t2) accurately - __CLC_DOUBLEN z1 = - __CLC_AS_GENTYPE(__CLC_AS_ULONGN(tp) & 0xffffffff00000000L); - __CLC_DOUBLEN z2 = t2 - (z1 - t1); - __CLC_DOUBLEN trec = -MATH_RECIP(tp); - __CLC_DOUBLEN trec_top = - __CLC_AS_GENTYPE(__CLC_AS_ULONGN(trec) & 0xffffffff00000000L); - - __CLC_DOUBLEN tpr = __clc_fma( - __clc_fma(trec_top, z2, __clc_fma(trec_top, z1, 1.0)), trec, trec_top); - - __CLC_DOUBLEN tpt = transform * (1.0 - MATH_DIVIDE(2.0 * tp, 1.0 + tp)); - __CLC_DOUBLEN tptr = transform * (MATH_DIVIDE(2.0 * tp, tp - 1.0) - 1.0); - - *leadval = c ? tpt : tp; - *tailval = c ? tptr : tpr; -} - // Reduction for small sized arguments _CLC_DEF _CLC_OVERLOAD __CLC_INTN __clc_remainder_piby2_small( __CLC_DOUBLEN x, private __CLC_DOUBLEN *rh, private __CLC_DOUBLEN *rt) {
diff --git a/clc/lib/generic/math/clc_sincospi.cl b/clc/lib/generic/math/clc_sincospi.cl new file mode 100644 index 0000000..53a2683 --- /dev/null +++ b/clc/lib/generic/math/clc_sincospi.cl
@@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clc/clc_convert.h" +#include "clc/float/definitions.h" +#include "clc/internal/clc.h" +#include "clc/math/clc_cos.h" +#include "clc/math/clc_fabs.h" +#include "clc/math/clc_sin.h" +#include "clc/math/clc_sincos_helpers.h" +#include "clc/math/clc_trigpi_helpers.h" +#include "clc/math/math.h" +#include "clc/relational/clc_isinf.h" +#include "clc/relational/clc_select.h" + +#define __CLC_BODY "clc_sincospi.inc" +#include "clc/math/gentype.inc"
diff --git a/clc/lib/generic/math/clc_sincospi.inc b/clc/lib/generic/math/clc_sincospi.inc new file mode 100644 index 0000000..b8b50a6 --- /dev/null +++ b/clc/lib/generic/math/clc_sincospi.inc
@@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +_CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE +__clc_sincospi(__CLC_GENTYPE x, __private __CLC_GENTYPE *cos_out) { + x = __clc_select(x, __CLC_GENTYPE_NAN, + __CLC_CONVERT_S_GENTYPE(__clc_isinf(x))); + + __CLC_GENTYPE absx = __clc_fabs(x); + + __CLC_GENTYPE reduced; + __CLC_INTN n = __clc_piArgReductionS(&reduced, absx); + + __CLC_SINCOS_RET_GENTYPE eval = __clc_sincospi_reduced_eval(reduced); + + __CLC_S_GENTYPE flip = __CLC_CONVERT_S_GENTYPE(n > 1) + ? __CLC_GENTYPE_S_SIGNBIT + : (__CLC_S_GENTYPE)0; + __CLC_S_GENTYPE odd = __CLC_CONVERT_S_GENTYPE((n & 1) != 0); + __CLC_GENTYPE s = odd ? eval.cos : eval.sin; + + __CLC_S_GENTYPE sin_val = __CLC_AS_S_GENTYPE(s) ^ flip ^ + (__CLC_AS_S_GENTYPE(absx) ^ __CLC_AS_S_GENTYPE(x)); + + __CLC_GENTYPE c = odd ? -eval.sin : eval.cos; + *cos_out = + __CLC_AS_GENTYPE(__CLC_CONVERT_S_GENTYPE(__CLC_AS_S_GENTYPE(c) ^ flip)); + return __CLC_AS_GENTYPE(sin_val); +} + +#define __CLC_SINCOSPI_DEF(addrspace) \ + _CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_sincospi( \ + __CLC_GENTYPE x, addrspace __CLC_GENTYPE *cos_out) { \ + \ + __CLC_GENTYPE cos_result; \ + __CLC_GENTYPE sin_result = __clc_sincospi(x, &cos_result); \ + *cos_out = cos_result; \ + return sin_result; \ + } + +__CLC_SINCOSPI_DEF(local) +__CLC_SINCOSPI_DEF(global) +#if _CLC_DISTINCT_GENERIC_AS_SUPPORTED +__CLC_SINCOSPI_DEF(generic) +#endif
diff --git a/clc/lib/generic/math/clc_sinpi.cl b/clc/lib/generic/math/clc_sinpi.cl index f9bed7e..bf57dc4 100644 --- a/clc/lib/generic/math/clc_sinpi.cl +++ b/clc/lib/generic/math/clc_sinpi.cl
@@ -6,12 +6,8 @@ // //===----------------------------------------------------------------------===// -#include "clc/clc_convert.h" -#include "clc/float/definitions.h" -#include "clc/internal/clc.h" -#include "clc/math/clc_fabs.h" -#include "clc/math/clc_sincos_helpers.h" -#include "clc/math/math.h" +#include "clc/math/clc_sincospi.h" +#include "clc/math/clc_sinpi.h" #define __CLC_BODY "clc_sinpi.inc" #include "clc/math/gentype.inc"
diff --git a/clc/lib/generic/math/clc_sinpi.inc b/clc/lib/generic/math/clc_sinpi.inc index 264609a..a6e5ee7 100644 --- a/clc/lib/generic/math/clc_sinpi.inc +++ b/clc/lib/generic/math/clc_sinpi.inc
@@ -6,109 +6,7 @@ // //===----------------------------------------------------------------------===// -#if __CLC_FPSIZE == 32 - _CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_sinpi(__CLC_GENTYPE x) { - __CLC_INTN ix = __CLC_AS_INTN(x); - __CLC_INTN xsgn = ix & (__CLC_INTN)0x80000000; - ix ^= xsgn; - __CLC_GENTYPE absx = __clc_fabs(x); - __CLC_INTN iax = __CLC_CONVERT_INTN(absx); - __CLC_GENTYPE r = absx - __CLC_CONVERT_GENTYPE(iax); - __CLC_INTN xodd = - xsgn ^ ((iax & 0x1) != 0 ? (__CLC_INTN)0x80000000 : (__CLC_INTN)0); - - // Initialize with return for +-Inf and NaN - __CLC_INTN ir = QNANBITPATT_SP32; - - // 2^23 <= |x| < Inf, the result is always integer - ir = ix < PINFBITPATT_SP32 ? xsgn : ir; - - // 0x1.0p-7 <= |x| < 2^23, result depends on which 0.25 interval - - // r < 1.0 - __CLC_GENTYPE a = 1.0f - r; - __CLC_INTN e = 0; - - // r <= 0.75 - __CLC_INTN c = r <= 0.75f; - a = c ? r - 0.5f : a; - e = c ? 1 : e; - - // r < 0.5 - c = r < 0.5f; - a = c ? 0.5f - r : a; - - // 0 < r <= 0.25 - c = r <= 0.25f; - a = c ? r : a; - e = c ? 0 : e; - - __CLC_GENTYPE sinval, cosval; - __clc_sincos_piby4(a * M_PI_F, &sinval, &cosval); - __CLC_INTN jr = xodd ^ __CLC_AS_INTN(e != 0 ? cosval : sinval); - - ir = ix < 0x4b000000 ? jr : ir; - - return __CLC_AS_GENTYPE(ir); + __CLC_GENTYPE unused_cos; + return __clc_sincospi(x, &unused_cos); } - -#elif __CLC_FPSIZE == 64 - -_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_sinpi(__CLC_GENTYPE x) { - __CLC_LONGN ix = __CLC_AS_LONGN(x); - __CLC_LONGN xsgn = ix & (__CLC_LONGN)0x8000000000000000L; - ix ^= xsgn; - __CLC_GENTYPE absx = __clc_fabs(x); - __CLC_LONGN iax = __CLC_CONVERT_LONGN(absx); - __CLC_GENTYPE r = absx - __CLC_CONVERT_GENTYPE(iax); - __CLC_LONGN xodd = - xsgn ^ - ((iax & 0x1L) != 0 ? (__CLC_LONGN)0x8000000000000000L : (__CLC_LONGN)0L); - - // Initialize with return for +-Inf and NaN - __CLC_LONGN ir = QNANBITPATT_DP64; - - // 2^23 <= |x| < Inf, the result is always integer - ir = ix < PINFBITPATT_DP64 ? xsgn : ir; - - // 0x1.0p-7 <= |x| < 2^23, result depends on which 0.25 interval - - // r < 1.0 - __CLC_GENTYPE a = 1.0 - r; - __CLC_LONGN e = 0; - - // r <= 0.75 - __CLC_LONGN c = r <= 0.75; - __CLC_GENTYPE t = r - 0.5; - a = c ? t : a; - e = c ? 1 : e; - - // r < 0.5 - c = r < 0.5; - t = 0.5 - r; - a = c ? t : a; - - // r <= 0.25 - c = r <= 0.25; - a = c ? r : a; - e = c ? 0 : e; - - __CLC_GENTYPE api = a * M_PI; - - __CLC_GENTYPE sinval, cosval; - __clc_sincos_piby4(api, 0.0, &sinval, &cosval); - __CLC_LONGN jr = xodd ^ __CLC_AS_LONGN(e != 0 ? cosval : sinval); - - ir = absx < 0x1.0p+52 ? jr : ir; - - return __CLC_AS_GENTYPE(ir); -} - -#elif __CLC_FPSIZE == 16 - -_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_sinpi(__CLC_GENTYPE x) { - return __CLC_CONVERT_GENTYPE(__clc_sinpi(__CLC_CONVERT_FLOATN(x))); -} - -#endif
diff --git a/clc/lib/generic/math/clc_tanpi.cl b/clc/lib/generic/math/clc_tanpi.cl index a75b544..0a1c872 100644 --- a/clc/lib/generic/math/clc_tanpi.cl +++ b/clc/lib/generic/math/clc_tanpi.cl
@@ -10,9 +10,13 @@ #include "clc/float/definitions.h" #include "clc/internal/clc.h" #include "clc/math/clc_fabs.h" +#include "clc/math/clc_mad.h" #include "clc/math/clc_native_recip.h" #include "clc/math/clc_sincos_helpers.h" +#include "clc/math/clc_trigpi_helpers.h" #include "clc/math/math.h" +#include "clc/relational/clc_isinf.h" +#include "clc/relational/clc_select.h" #define __CLC_BODY "clc_tanpi.inc" #include "clc/math/gentype.inc"
diff --git a/clc/lib/generic/math/clc_tanpi.inc b/clc/lib/generic/math/clc_tanpi.inc index 3a2f5dc..c9ba47a 100644 --- a/clc/lib/generic/math/clc_tanpi.inc +++ b/clc/lib/generic/math/clc_tanpi.inc
@@ -8,125 +8,82 @@ #if __CLC_FPSIZE == 32 -_CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_tanpi(__CLC_GENTYPE x) { - __CLC_INTN ix = __CLC_AS_INTN(x); - __CLC_INTN xsgn = ix & (__CLC_INTN)SIGNBIT_SP32; - __CLC_INTN xnsgn = xsgn ^ (__CLC_INTN)SIGNBIT_SP32; - ix ^= xsgn; - __CLC_GENTYPE absx = __clc_fabs(x); - __CLC_INTN iax = __CLC_CONVERT_INTN(absx); - __CLC_GENTYPE r = absx - __CLC_CONVERT_GENTYPE(iax); - __CLC_INTN xodd = xsgn ^ __CLC_AS_INTN((iax & 0x1) != 0 ? SIGNBIT_SP32 : 0); +_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_GENTYPE +__clc_tanpi_reduced_eval(__CLC_GENTYPE x, __CLC_INTN is_odd) { + __CLC_GENTYPE s = x * x; - // Initialize with return for +-Inf and NaN - __CLC_INTN ir = QNANBITPATT_SP32; + __CLC_GENTYPE t = __clc_mad(s, __clc_mad(s, __clc_mad(s, __clc_mad(s, + __clc_mad(s, __clc_mad(s, + 0x1.7d2bd4p+16f, 0x1.a4d306p+12f), 0x1.435004p+11f), 0x1.4b6926p+9f), + 0x1.451e22p+7f), 0x1.467a9cp+5f), 0x1.4abb6ap+3f); - // 2^24 <= |x| < Inf, the result is always even integer - ir = ix < PINFBITPATT_SP32 ? xsgn : ir; + t = x * s * t; + t = __clc_mad(x, 0x1.921fb6p+1f, t); - // 2^23 <= |x| < 2^24, the result is always integer - ir = ix < 0x4b800000 ? xodd : ir; + __CLC_GENTYPE tr = __CLC_FP_LIT(-1.0) / t; - // 0x1.0p-7 <= |x| < 2^23, result depends on which 0.25 interval - - // r < 1.0 - __CLC_GENTYPE a = 1.0f - r; - __CLC_INTN e = 0; - __CLC_INTN s = xnsgn; - - // r <= 0.75 - __CLC_INTN c = r <= 0.75f; - a = c ? r - 0.5f : a; - e = c ? 1 : e; - s = c ? xsgn : s; - - // r < 0.5 - c = r < 0.5f; - a = c ? 0.5f - r : a; - s = c ? xnsgn : s; - - // 0 < r <= 0.25 - c = r <= 0.25f; - a = c ? r : a; - e = c ? 0 : e; - s = c ? xsgn : s; - - __CLC_GENTYPE t = __clc_tanf_piby4(a * M_PI_F, 0); - __CLC_GENTYPE tr = -__clc_native_recip(t); - __CLC_INTN jr = s ^ __CLC_AS_INTN(e != 0 ? tr : t); - - jr = r == 0.5f ? xodd | 0x7f800000 : jr; - - ir = ix < 0x4b000000 ? jr : ir; - - return __CLC_AS_GENTYPE(ir); + return is_odd ? tr : t; } #elif __CLC_FPSIZE == 64 -_CLC_DEF _CLC_OVERLOAD __CLC_GENTYPE __clc_tanpi(__CLC_GENTYPE x) { - __CLC_LONGN ix = __CLC_AS_LONGN(x); - __CLC_LONGN xsgn = ix & (__CLC_LONGN)0x8000000000000000L; - __CLC_LONGN xnsgn = xsgn ^ (__CLC_LONGN)0x8000000000000000L; - ix ^= xsgn; - __CLC_GENTYPE absx = __clc_fabs(x); - __CLC_LONGN iax = __CLC_CONVERT_LONGN(absx); - __CLC_GENTYPE r = absx - __CLC_CONVERT_GENTYPE(iax); - __CLC_LONGN xodd = - xsgn ^ __CLC_AS_LONGN((iax & 0x1) != 0 ? 0x8000000000000000L : 0L); +_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_DOUBLEN +__clc_tanpi_reduced_eval(__CLC_DOUBLEN x, __CLC_INTN is_odd) { + __CLC_GENTYPE s = x * x; + __CLC_GENTYPE t = __clc_mad(s, __clc_mad(s, __clc_mad(s, __clc_mad(s, + __clc_mad(s, __clc_mad(s, __clc_mad(s, __clc_mad(s, + __clc_mad(s, __clc_mad(s, __clc_mad(s, __clc_mad(s, + __clc_mad(s, + 0x1.3fad0a71ea6d1p+32, -0x1.11a76ac97377bp+30), 0x1.ba2bcaca6da1bp+27), -0x1.79e8e2d7aaf57p+22), + 0x1.c1c1102e46eccp+21), 0x1.31291bbcb5588p+19), 0x1.486b2d6bb3db2p+17), 0x1.45be1b46ff156p+15), + 0x1.45f61b419c746p+13), 0x1.45f311045a4ffp+11), 0x1.45f4739a998c7p+9), 0x1.45fff9b243050p+7), + 0x1.466bc6775cf74p+5), 0x1.4abbce625be8bp+3); + t = x * s * t; + t = __clc_mad(x, 0x1.921fb54442d18p+1, t); - // Initialize with return for +-Inf and NaN - __CLC_LONGN ir = QNANBITPATT_DP64; + __CLC_GENTYPE tr = __CLC_FP_LIT(-1.0) / t; - // 2^53 <= |x| < Inf, the result is always even integer - ir = ix < PINFBITPATT_DP64 ? xsgn : ir; - - // 2^52 <= |x| < 2^53, the result is always integer - ir = ix < 0x4340000000000000L ? xodd : ir; - - // 0x1.0p-14 <= |x| < 2^53, result depends on which 0.25 interval - - // r < 1.0 - __CLC_GENTYPE a = 1.0 - r; - __CLC_LONGN e = 0; - __CLC_LONGN s = xnsgn; - - // r <= 0.75 - __CLC_LONGN c = r <= 0.75; - __CLC_GENTYPE t = r - 0.5; - a = c ? t : a; - e = c ? 1 : e; - s = c ? xsgn : s; - - // r < 0.5 - c = r < 0.5; - t = 0.5 - r; - a = c ? t : a; - s = c ? xnsgn : s; - - // r <= 0.25 - c = r <= 0.25; - a = c ? r : a; - e = c ? 0 : e; - s = c ? xsgn : s; - - __CLC_GENTYPE api = a * M_PI; - __CLC_GENTYPE lo, hi; - __clc_tan_piby4(api, 0.0, &lo, &hi); - __CLC_LONGN jr = s ^ __CLC_AS_LONGN(e != 0 ? hi : lo); - - __CLC_LONGN si = xodd | 0x7ff0000000000000L; - jr = r == 0.5 ? si : jr; - - ir = ix < 0x4330000000000000L ? jr : ir; - - return __CLC_AS_GENTYPE(ir); + return __CLC_CONVERT_LONGN(is_odd) ? tr : t; } #elif __CLC_FPSIZE == 16 -_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_tanpi(__CLC_GENTYPE x) { - return __CLC_CONVERT_GENTYPE(__clc_tanpi(__CLC_CONVERT_FLOATN(x))); +_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_HALFN +__clc_tanpi_reduced_eval(__CLC_HALFN x, __CLC_INTN is_odd) { + __CLC_HALFN s = x * x; + + __CLC_HALFN t = + __clc_mad(s, __clc_mad(s, 0x1.3d8p+8h, 0x1.fe4p+4h), 0x1.508p+3h); + + t = x * s * t; + t = __clc_mad(x, 0x1.92p+1h, t); + + __CLC_HALFN tr = __CLC_FP_LIT(-1.0) / t; + + return __CLC_CONVERT_SHORTN(is_odd) ? tr : t; } #endif + +_CLC_DEF _CLC_OVERLOAD _CLC_CONST __CLC_GENTYPE __clc_tanpi(__CLC_GENTYPE x) { + x = __clc_select(x, __CLC_GENTYPE_NAN, + __CLC_CONVERT_S_GENTYPE(__clc_isinf(x))); + + __CLC_GENTYPE absx = __clc_fabs(x); + + __CLC_GENTYPE reduced; + __CLC_INTN n = __clc_piArgReductionS(&reduced, absx); + + __CLC_GENTYPE t = __clc_tanpi_reduced_eval(reduced, (n & 1) != 0); + + __CLC_S_GENTYPE n_1_or_2 = __CLC_CONVERT_S_GENTYPE((n == 1) || (n == 2)); + + __CLC_S_GENTYPE flip = (n_1_or_2 && (reduced == __CLC_FP_LIT(0.0))) + ? __CLC_GENTYPE_S_SIGNBIT + : (__CLC_S_GENTYPE)0; + + __CLC_S_GENTYPE result = (__CLC_AS_S_GENTYPE(t) ^ flip) ^ + (__CLC_AS_S_GENTYPE(x) & __CLC_GENTYPE_S_SIGNBIT); + + return __CLC_AS_GENTYPE(result); +}
diff --git a/clc/lib/generic/math/clc_trigpi_helpers.cl b/clc/lib/generic/math/clc_trigpi_helpers.cl new file mode 100644 index 0000000..bb3e47a --- /dev/null +++ b/clc/lib/generic/math/clc_trigpi_helpers.cl
@@ -0,0 +1,16 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clc/clc_convert.h" +#include "clc/math/clc_fract.h" +#include "clc/math/clc_mad.h" +#include "clc/math/clc_rint.h" +#include "clc/math/clc_trigpi_helpers.h" + +#define __CLC_BODY "clc_trigpi_helpers.inc" +#include "clc/math/gentype.inc"
diff --git a/clc/lib/generic/math/clc_trigpi_helpers.inc b/clc/lib/generic/math/clc_trigpi_helpers.inc new file mode 100644 index 0000000..7dd0b03 --- /dev/null +++ b/clc/lib/generic/math/clc_trigpi_helpers.inc
@@ -0,0 +1,19 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +_CLC_DEF _CLC_OVERLOAD __CLC_INTN +__clc_piArgReductionS(private __CLC_GENTYPE *reduced, __CLC_GENTYPE x) { + __CLC_GENTYPE unused; + __CLC_GENTYPE t = + __CLC_FP_LIT(2.0) * __clc_fract(__CLC_FP_LIT(0.5) * x, &unused); + x = x > __CLC_FP_LIT(1.0) ? t : x; + t = __clc_rint(__CLC_FP_LIT(2.0) * x); + + *reduced = __clc_mad(t, __CLC_FP_LIT(-0.5), x); + return __CLC_CONVERT_INTN(t) & 0x3; +}