Fix the sign issue on pown().
Change-Id: I9ee826c81c14f7c3ed137608643e5cfc0f078bce
diff --git a/driver/runtime/rs_cl.c b/driver/runtime/rs_cl.c
index a408197..3a9252a 100644
--- a/driver/runtime/rs_cl.c
+++ b/driver/runtime/rs_cl.c
@@ -513,20 +513,15 @@
FN_FUNC_FN_FN(pow)
extern float __attribute__((overloadable)) pown(float v, int p) {
- return pow(v, (float)p);
+ /* The mantissa of a float has fewer bits than an int (24 effective vs. 31).
+ * For very large ints, we'll lose whether the exponent is even or odd, making
+ * the selection of a correct sign incorrect. We correct this.
+ */
+ float sign = (v < 0.0f && (p & 0x1)) ? -1.0 : 1.0;
+ float f = pow(v, (float)p);
+ return copysign(f, sign);
}
-extern float2 __attribute__((overloadable)) pown(float2 v, int2 p) {
- float2 f2 = convert_float2(p);
- return pow(v, f2);
-}
-extern float3 __attribute__((overloadable)) pown(float3 v, int3 p) {
- float3 f3 = convert_float3(p);
- return pow(v, f3);
-}
-extern float4 __attribute__((overloadable)) pown(float4 v, int4 p) {
- float4 f4 = convert_float4(p);
- return pow(v, f4);
-}
+FN_FUNC_FN_IN(pown)
extern float __attribute__((overloadable)) powr(float v, float p) {
return pow(v, p);