summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrander <rander.wang@intel.com>2017-04-07 15:27:46 +0800
committerYang Rong <rong.r.yang@intel.com>2017-05-04 19:08:31 +0800
commit8cf4cb179e19584f5a041673e494ceb7b51a24d5 (patch)
treeb140446bfcbc507943b587adbcb4905e5f4957f2
parent21be43f13ac3dfd839e86a0dc180ec0a7d1c0e0f (diff)
downloadbeignet-8cf4cb179e19584f5a041673e494ceb7b51a24d5.tar.gz
backend: refine powr to pass cft
add path to all the corner case Signed-off-by: rander.wang <rander.wang@intel.com> Tested-by: Yang Rong <rong.r.yang@intel.com>
-rw-r--r--backend/src/libocl/tmpl/ocl_math_common.tmpl.cl56
1 files changed, 43 insertions, 13 deletions
diff --git a/backend/src/libocl/tmpl/ocl_math_common.tmpl.cl b/backend/src/libocl/tmpl/ocl_math_common.tmpl.cl
index 883ec09b..8c5d54b4 100644
--- a/backend/src/libocl/tmpl/ocl_math_common.tmpl.cl
+++ b/backend/src/libocl/tmpl/ocl_math_common.tmpl.cl
@@ -2530,29 +2530,59 @@ OVERLOADABLE double pown(double x, int n)
OVERLOADABLE double powr(double x, double y)
{
- int hx,hy,ix,iy;
- unsigned lx,ly;
+ ulong ux, uy;
+ ulong lx, ly;
- hx = __HI(x); lx = __LO(x);
- hy = __HI(y); ly = __LO(y);
- ix = hx&0x7fffffff; iy = hy&0x7fffffff;
-
- /* y==zero: x**0 = 1 */
- if((iy|ly)==0) return 1.0;
+ lx = as_ulong(x);
+ ly = as_ulong(y);
+ ux = lx & DF_ABS_MASK;
+ uy = ly & DF_ABS_MASK;
- if(x < 0)return as_double(DF_ABS_MASK);
+ if(lx > DF_SIGN_MASK)return as_double(DF_POSITIVE_INF + 1);
/* +-NaN return x+y */
- if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)))
+ if(ux > DF_POSITIVE_INF)
return x+y;
- if(iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
+ if(uy > DF_POSITIVE_INF)
{
return x + y;
}
- if(((ix==0x7ff00000)&&(lx==0)) && ((iy==0x7ff00000)&&(ly==0)))
- return as_double(DF_ABS_MASK);
+ if(uy ==0 && ux == 0) return as_double(DF_POSITIVE_INF + 1);
+
+ if((lx == DF_POSITIVE_INF) && (ly == DF_POSITIVE_INF))
+ return as_double(DF_POSITIVE_INF);
+
+ if((lx == DF_POSITIVE_INF) && (ly == DF_NEGTIVE_INF))
+ return 0.0;
+
+ if((lx == DF_POSITIVE_INF) && (uy == 0))
+ return as_double(DF_POSITIVE_INF + 1);
+
+ if(ly == DF_POSITIVE_INF && ux == 0)
+ return 0.0;
+
+ if(ly == DF_NEGTIVE_INF && ux == 0)
+ return as_double(DF_POSITIVE_INF);
+
+ if(ly < DF_SIGN_MASK && ux == 0)
+ return 0.0;
+
+ if(ly > DF_SIGN_MASK && ux == 0)
+ return as_double(DF_POSITIVE_INF);
+
+ if(ly == DF_NEGTIVE_INF && x > 1.0)
+ return 0.0;
+
+ if(ly == DF_NEGTIVE_INF && x < 1.0)
+ return as_double(DF_POSITIVE_INF);
+
+ if(ly == DF_NEGTIVE_INF && x == 1.0)
+ return as_double(DF_POSITIVE_INF + 1);
+
+ if(ly == DF_POSITIVE_INF && x == 1.0)
+ return as_double(DF_POSITIVE_INF + 1);
return __ocl_internal_pow(x, y);
}