[Beignet] [PATCH 2/6] GBE: fix bug in pow/pown.

Zhigang Gong zhigang.gong at intel.com
Tue Nov 4 21:41:12 PST 2014


pow/pown ignore the sign of their first argument (e.g. pow(-2,3) gives
8 instead of -8)

This patch is from:
https://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=Fix-pow-erf-tgamma.patch;att=3;bug=768090

Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
 backend/src/libocl/script/ocl_math.def   |  3 +--
 backend/src/libocl/tmpl/ocl_math.tmpl.cl | 20 ++++++++++++++++----
 backend/src/libocl/tmpl/ocl_math.tmpl.h  |  2 +-
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/backend/src/libocl/script/ocl_math.def b/backend/src/libocl/script/ocl_math.def
index 4baded4..5617c09 100644
--- a/backend/src/libocl/script/ocl_math.def
+++ b/backend/src/libocl/script/ocl_math.def
@@ -94,8 +94,7 @@ floatn pown (floatn x, intn y)
 float pown (float x, int y)
 doublen pown (doublen x, intn y)
 double pown (double x, int y)
-#XXX we define powr as pow
-#gentype powr (gentype x, gentype y)
+gentype powr (gentype x, gentype y)
 gentype remainder (gentype x, gentype y)
 floatn remquo (floatn x, floatn y, __global intn *quo)
 floatn remquo (floatn x, floatn y, __local intn *quo)
diff --git a/backend/src/libocl/tmpl/ocl_math.tmpl.cl b/backend/src/libocl/tmpl/ocl_math.tmpl.cl
index f61d107..8a3dd25 100644
--- a/backend/src/libocl/tmpl/ocl_math.tmpl.cl
+++ b/backend/src/libocl/tmpl/ocl_math.tmpl.cl
@@ -2695,8 +2695,6 @@ OVERLOADABLE float atanh(float x) {
   return __gen_ocl_internal_atanh(x);
 }
 
-#define pow powr
-
 OVERLOADABLE float cbrt(float x) {
   if (__ocl_math_fastpath_flag)
     return __gen_ocl_internal_fastpath_cbrt(x);
@@ -3198,11 +3196,25 @@ OVERLOADABLE float remquo(float x, float y, private int *quo) { BODY; }
 #undef BODY
 
 OVERLOADABLE float pown(float x, int n) {
-  if (x == 0 && n == 0)
-    return 1;
+  if (x == 0.f && n == 0)
+    return 1.f;
+  if (x < 0.f && (n&1) )
+    return -powr(-x, n);
   return powr(x, n);
 }
 
+OVERLOADABLE float pow(float x, float y) {
+  int n;
+  if (x == 0.f && y == 0.f)
+    return 1.f;
+  if (x >= 0.f)
+    return powr(x, y);
+  n = y;
+  if ((float)n == y)//is exact integer
+    return pown(x, n);
+  return NAN;
+}
+
 OVERLOADABLE float rootn(float x, int n) {
   float ax,re;
   int sign = 0;
diff --git a/backend/src/libocl/tmpl/ocl_math.tmpl.h b/backend/src/libocl/tmpl/ocl_math.tmpl.h
index a86576a..e5ea2a4 100644
--- a/backend/src/libocl/tmpl/ocl_math.tmpl.h
+++ b/backend/src/libocl/tmpl/ocl_math.tmpl.h
@@ -46,8 +46,8 @@ OVERLOADABLE float fmod (float x, float y);
 OVERLOADABLE float remainder(float x, float p);
 OVERLOADABLE float ldexp(float x, int n);
 OVERLOADABLE float powr(float x, float y);
+OVERLOADABLE float pow(float x, float y);
 //no pow, we use powr instead
-#define pow powr
 OVERLOADABLE float fabs(float x);
 OVERLOADABLE float trunc(float x);
 OVERLOADABLE float round(float x);
-- 
1.8.3.2



More information about the Beignet mailing list