summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuiling Song <ruiling.song@intel.com>2014-12-09 10:24:43 +0800
committerZhigang Gong <zhigang.gong@intel.com>2014-12-15 09:53:51 +0800
commit1795f38f18c3881201249a2502f20b63a0f0d47a (patch)
tree9f34ab149f9f7751a56e59af13ea328709bd8a91
parent222030b4f30001679a7b19b1f8bad0653cc6be73 (diff)
libocl: Fix precision of builtin tanpi.
This was originally submitted in f2111f368d9d7eeafe1762ecb0160d9da69d9214 But it was missed during libocl change. So add it back here. Signed-off-by: Ruiling Song <ruiling.song@intel.com> Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
-rw-r--r--backend/src/libocl/tmpl/ocl_math.tmpl.cl28
1 files changed, 27 insertions, 1 deletions
diff --git a/backend/src/libocl/tmpl/ocl_math.tmpl.cl b/backend/src/libocl/tmpl/ocl_math.tmpl.cl
index 236fa0b1..ddfde830 100644
--- a/backend/src/libocl/tmpl/ocl_math.tmpl.cl
+++ b/backend/src/libocl/tmpl/ocl_math.tmpl.cl
@@ -1528,7 +1528,33 @@ OVERLOADABLE float nan(uint code) {
return NAN;
}
OVERLOADABLE float __gen_ocl_internal_tanpi(float x) {
- return native_tan(x * M_PI_F);
+ float sign = 1.0f;
+ int ix;
+ if(isinf(x)) return NAN;
+ if(x < 0.0f) { x = -x; sign = -1.0f; }
+ GEN_OCL_GET_FLOAT_WORD(ix, x);
+ if(x> 0x1.0p24) return 0.0f;
+ float m = __gen_ocl_internal_floor(x);
+ ix = (int)m;
+ m = x-m;
+ int n = __gen_ocl_internal_floor(m*4.0f);
+ if(m == 0.5f) {
+ return (ix&0x1) == 0 ? sign*INFINITY : sign*-INFINITY;
+ }
+ if(m == 0.0f) {
+ return (ix&0x1) == 0 ? 0.0f : -0.0f;
+ }
+
+ switch(n) {
+ case 0:
+ return sign * __kernel_tanf(m*M_PI_F, 0.0f, 1);
+ case 1:
+ return sign * 1.0f/__kernel_tanf((0.5f-m)*M_PI_F, 0.0f, 1);
+ case 2:
+ return sign * 1.0f/__kernel_tanf((0.5f-m)*M_PI_F, 0.0f, 1);
+ default:
+ return sign * -1.0f*__kernel_tanf((1.0f-m)*M_PI_F, 0.0f, 1);
+ }
}
OVERLOADABLE float __gen_ocl_internal_cbrt(float x) {
/* copied from fdlibm */