[X86] Better handling of impossibly large stack frames (#124217)
[llvm-project.git] / libclc / generic / lib / math / sinh.cl
blob23500c1f49b7a0f4e16019ab002fce972bd4d55c
1 /*
2 * Copyright (c) 2014 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
23 #include <clc/clc.h>
24 #include <clc/clcmacro.h>
26 #include "math.h"
27 #include "tables.h"
29 _CLC_OVERLOAD _CLC_DEF float sinh(float x)
31 // After dealing with special cases the computation is split into regions as follows.
32 // abs(x) >= max_sinh_arg:
33 // sinh(x) = sign(x)*Inf
34 // abs(x) >= small_threshold:
35 // sinh(x) = sign(x)*exp(abs(x))/2 computed using the splitexp and scaleDouble functions as for exp_amd().
36 // abs(x) < small_threshold:
37 // compute p = exp(y) - 1 and then z = 0.5*(p+(p/(p+1.0)))
38 // sinh(x) is then sign(x)*z.
40 const float max_sinh_arg = 0x1.65a9fap+6f;
41 const float small_threshold = 0x1.0a2b24p+3f;
43 uint ux = as_uint(x);
44 uint aux = ux & EXSIGNBIT_SP32;
45 uint xs = ux ^ aux;
46 float y = as_float(aux);
48 // We find the integer part y0 of y and the increment dy = y - y0. We then compute
49 // z = sinh(y) = sinh(y0)cosh(dy) + cosh(y0)sinh(dy)
50 // where sinh(y0) and cosh(y0) are tabulated above.
51 int ind = (int) y;
52 ind = (uint)ind > 36U ? 0 : ind;
54 float dy = y - ind;
55 float dy2 = dy * dy;
57 float sdy = mad(dy2,
58 mad(dy2,
59 mad(dy2,
60 mad(dy2,
61 mad(dy2,
62 mad(dy2, 0.7746188980094184251527126e-12f, 0.160576793121939886190847e-9f),
63 0.250521176994133472333666e-7f),
64 0.275573191913636406057211e-5f),
65 0.198412698413242405162014e-3f),
66 0.833333333333329931873097e-2f),
67 0.166666666666666667013899e0f);
68 sdy = mad(sdy, dy*dy2, dy);
70 float cdy = mad(dy2,
71 mad(dy2,
72 mad(dy2,
73 mad(dy2,
74 mad(dy2,
75 mad(dy2, 0.1163921388172173692062032e-10f, 0.208744349831471353536305e-8f),
76 0.275573350756016588011357e-6f),
77 0.248015872460622433115785e-4f),
78 0.138888888889814854814536e-2f),
79 0.416666666666660876512776e-1f),
80 0.500000000000000005911074e0f);
81 cdy = mad(cdy, dy2, 1.0f);
83 float2 tv = USE_TABLE(sinhcosh_tbl, ind);
84 float z = mad(tv.s1, sdy, tv.s0 * cdy);
85 z = as_float(xs | as_uint(z));
87 // When y is large enough so that the negative exponential is negligible,
88 // so sinh(y) is approximated by sign(x)*exp(y)/2.
89 float t = exp(y - 0x1.62e500p-1f);
90 float zsmall = mad(0x1.a0210ep-18f, t, t);
91 zsmall = as_float(xs | as_uint(zsmall));
92 z = y >= small_threshold ? zsmall : z;
94 // Corner cases
95 float zinf = as_float(PINFBITPATT_SP32 | xs);
96 z = y >= max_sinh_arg ? zinf : z;
97 z = aux > PINFBITPATT_SP32 | aux < 0x38800000U ? x : z;
99 return z;
102 _CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, sinh, float);
104 #ifdef cl_khr_fp64
105 #pragma OPENCL EXTENSION cl_khr_fp64 : enable
107 _CLC_OVERLOAD _CLC_DEF double sinh(double x)
109 // After dealing with special cases the computation is split into
110 // regions as follows:
112 // abs(x) >= max_sinh_arg:
113 // sinh(x) = sign(x)*Inf
115 // abs(x) >= small_threshold:
116 // sinh(x) = sign(x)*exp(abs(x))/2 computed using the
117 // splitexp and scaleDouble functions as for exp_amd().
119 // abs(x) < small_threshold:
120 // compute p = exp(y) - 1 and then z = 0.5*(p+(p/(p+1.0)))
121 // sinh(x) is then sign(x)*z.
123 const double max_sinh_arg = 7.10475860073943977113e+02; // 0x408633ce8fb9f87e
125 // This is where exp(-x) is insignificant compared to exp(x) = ln(2^27)
126 const double small_threshold = 0x1.2b708872320e2p+4;
128 double y = fabs(x);
130 // In this range we find the integer part y0 of y
131 // and the increment dy = y - y0. We then compute
132 // z = sinh(y) = sinh(y0)cosh(dy) + cosh(y0)sinh(dy)
133 // where sinh(y0) and cosh(y0) are obtained from tables
135 int ind = min((int)y, 36);
136 double dy = y - ind;
137 double dy2 = dy * dy;
139 double sdy = dy * dy2 *
140 fma(dy2,
141 fma(dy2,
142 fma(dy2,
143 fma(dy2,
144 fma(dy2,
145 fma(dy2, 0.7746188980094184251527126e-12, 0.160576793121939886190847e-9),
146 0.250521176994133472333666e-7),
147 0.275573191913636406057211e-5),
148 0.198412698413242405162014e-3),
149 0.833333333333329931873097e-2),
150 0.166666666666666667013899e0);
152 double cdy = dy2 * fma(dy2,
153 fma(dy2,
154 fma(dy2,
155 fma(dy2,
156 fma(dy2,
157 fma(dy2, 0.1163921388172173692062032e-10, 0.208744349831471353536305e-8),
158 0.275573350756016588011357e-6),
159 0.248015872460622433115785e-4),
160 0.138888888889814854814536e-2),
161 0.416666666666660876512776e-1),
162 0.500000000000000005911074e0);
164 // At this point sinh(dy) is approximated by dy + sdy.
165 // Shift some significant bits from dy to sdy.
166 double sdy1 = as_double(as_ulong(dy) & 0xfffffffff8000000UL);
167 double sdy2 = sdy + (dy - sdy1);
169 double2 tv = USE_TABLE(cosh_tbl, ind);
170 double cl = tv.s0;
171 double ct = tv.s1;
172 tv = USE_TABLE(sinh_tbl, ind);
173 double sl = tv.s0;
174 double st = tv.s1;
176 double z = fma(cl, sdy1, fma(sl, cdy, fma(cl, sdy2, fma(ct, sdy1, fma(st, cdy, ct*sdy2)) + st))) + sl;
178 // Other cases
179 z = (y < 0x1.0p-28) | isnan(x) | isinf(x) ? y : z;
181 double t = exp(y - 0x1.62e42fefa3800p-1);
182 t = fma(t, -0x1.ef35793c76641p-45, t);
183 z = y >= small_threshold ? t : z;
184 z = y >= max_sinh_arg ? as_double(PINFBITPATT_DP64) : z;
186 return copysign(z, x);
189 _CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, sinh, double)
191 #endif
193 #ifdef cl_khr_fp16
195 #pragma OPENCL EXTENSION cl_khr_fp16 : enable
197 _CLC_DEFINE_UNARY_BUILTIN_FP16(sinh)
199 #endif