From 0bea84b2d46dc7162c38fc265808ab552eb68eaa Mon Sep 17 00:00:00 2001 From: Bruce Evans Date: Mon, 28 Nov 2005 06:15:10 +0000 Subject: [PATCH] Exploit skew-symmetry to avoid an operation: -sin(x-A) = sin(A-x). This gives a tiny but hopefully always free optimization in the 2 quadrants to which it applies. On Athlons, it reduces maximum latency by 4 cycles in these quadrants but has usually has a smaller effect on total time (typically ~2 cycles (~5%), but sometimes 8 cycles when the compiler generates poor code). --- lib/msun/src/s_cosf.c | 4 ++-- lib/msun/src/s_sinf.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/msun/src/s_cosf.c b/lib/msun/src/s_cosf.c index 42664e22f37b..84fbc6d24e74 100644 --- a/lib/msun/src/s_cosf.c +++ b/lib/msun/src/s_cosf.c @@ -48,7 +48,7 @@ cosf(float x) } if(ix<=0x407b53d1) { /* |x| ~<= 5*pi/4 */ if(ix<=0x4016cbe3) /* |x| ~<= 3pi/4 */ - return -__kernel_sindf(x - c1pio2); + return __kernel_sindf(c1pio2 - x); else return -__kernel_cosdf(x - c2pio2); } @@ -67,7 +67,7 @@ cosf(float x) n = __ieee754_rem_pio2f(x,y); switch(n&3) { case 0: return __kernel_cosdf((double)y[0]+y[1]); - case 1: return -__kernel_sindf((double)y[0]+y[1]); + case 1: return __kernel_sindf(-(double)y[0]-y[1]); case 2: return -__kernel_cosdf((double)y[0]+y[1]); default: return __kernel_sindf((double)y[0]+y[1]); diff --git a/lib/msun/src/s_sinf.c b/lib/msun/src/s_sinf.c index dc46a6895cb4..5842014bb809 100644 --- a/lib/msun/src/s_sinf.c +++ b/lib/msun/src/s_sinf.c @@ -53,7 +53,7 @@ sinf(float x) else return -__kernel_cosdf(x + s1pio2); } else - return -__kernel_sindf(x + (hx > 0 ? -s2pio2 : s2pio2)); + return __kernel_sindf((hx > 0 ? s2pio2 : -s2pio2) - x); } if(ix<=0x40e231d5) { /* |x| ~<= 9*pi/4 */ if(ix<=0x40afeddf) { /* |x| ~<= 7*pi/4 */ @@ -74,7 +74,7 @@ sinf(float x) switch(n&3) { case 0: return __kernel_sindf((double)y[0]+y[1]); case 1: return __kernel_cosdf((double)y[0]+y[1]); - case 2: return -__kernel_sindf((double)y[0]+y[1]); + case 2: return __kernel_sindf(-(double)y[0]-y[1]); default: return -__kernel_cosdf((double)y[0]+y[1]); }