mirror of git://gcc.gnu.org/git/gcc.git
Here is a cherry-pick from glibc [BZ #32411] fix. As mentioned by the reporter in a pull request against gcc-mirror, the THREEp96 constant in e_expl.c is incorrect, it is actually 0x3.p+94f128 rather than 0x3.p+96f128. The algorithm uses that to compute the t2 integer (tval2), by whose delta it adjusts the x+xl pair and then in the result uses the precomputed exp value for that entry. Using 0x3.p+94f128 rather than 0x3.p+96f128 results in tval2 sometimes being one smaller, sometimes one larger than the desired value, thus can mean the x+xl pair after adjustment will be larger in absolute value than it should be. DesWursters created a test program for this https://github.com/DesWurstes/comparefloats and his results were total: 1135000000 not_equal: 4322 earlier_score: 674 later_score: 3648 I've modified this so with https://sourceware.org/bugzilla/show_bug.cgi?id=32411#c3 so that it actually tests pseudo-random _Float128 values with range (-16384.,16384) with strong bias on values larger than 0.0002 in absolute value (so that tval1/tval2 aren't zero most of the time) and that gave total: 10000000000 not_equal: 29861 earlier_score: 4606 later_score: 25255 So, in both cases, in most cases the change doesn't result in any differences, and in those rare cases where does, about 85% have smaller ulp than without the patch. Additionally I've tried https://sourceware.org/bugzilla/show_bug.cgi?id=32411#c4 and in 2 billion iterations it didn't find any case where x+xl after the adjustments without this change would be smaller in absolute value compared to x+xl after the adjustments with this change. 2025-04-09 Jakub Jelinek <jakub@redhat.com> * math/expq.c (C): Fix up THREEp96 constant. |
||
|---|---|---|
| .. | ||
| acoshq.c | ||
| acosq.c | ||
| asinhq.c | ||
| asinq.c | ||
| atan2q.c | ||
| atanhq.c | ||
| atanq.c | ||
| cacoshq.c | ||
| cacosq.c | ||
| casinhq.c | ||
| casinhq_kernel.c | ||
| casinq.c | ||
| catanhq.c | ||
| catanq.c | ||
| cbrtq.c | ||
| ccoshq.c | ||
| ceilq.c | ||
| cexpq.c | ||
| cimagq.c | ||
| clog10q.c | ||
| clogq.c | ||
| complex.c | ||
| conjq.c | ||
| copysignq.c | ||
| coshq.c | ||
| cosq.c | ||
| cosq_kernel.c | ||
| cprojq.c | ||
| crealq.c | ||
| csinhq.c | ||
| csinq.c | ||
| csqrtq.c | ||
| ctanhq.c | ||
| ctanq.c | ||
| erfq.c | ||
| exp2q.c | ||
| expm1q.c | ||
| expq.c | ||
| expq_table.h | ||
| fabsq.c | ||
| fdimq.c | ||
| finiteq.c | ||
| floorq.c | ||
| fmaq.c | ||
| fmaxq.c | ||
| fminq.c | ||
| fmodq.c | ||
| frexpq.c | ||
| hypotq.c | ||
| ilogbq.c | ||
| isinfq.c | ||
| isnanq.c | ||
| issignalingq.c | ||
| j0q.c | ||
| j1q.c | ||
| jnq.c | ||
| ldexpq.c | ||
| lgammaq.c | ||
| lgammaq_neg.c | ||
| lgammaq_product.c | ||
| llrintq.c | ||
| llroundq.c | ||
| log1pq.c | ||
| log2q.c | ||
| log10q.c | ||
| logbq.c | ||
| logq.c | ||
| lrintq.c | ||
| lroundq.c | ||
| modfq.c | ||
| nanq.c | ||
| nearbyintq.c | ||
| nextafterq.c | ||
| powq.c | ||
| rem_pio2q.c | ||
| remainderq.c | ||
| remquoq.c | ||
| rintq.c | ||
| roundq.c | ||
| scalblnq.c | ||
| scalbnq.c | ||
| signbitq.c | ||
| sincos_table.c | ||
| sincosq.c | ||
| sincosq_kernel.c | ||
| sinhq.c | ||
| sinq.c | ||
| sinq_kernel.c | ||
| sqrtq.c | ||
| tanhq.c | ||
| tanq.c | ||
| tanq_kernel.c | ||
| tgammaq.c | ||
| tgammaq_product.c | ||
| truncq.c | ||
| x2y2m1q.c | ||