[Beignet] [PATCH] fix one bug of long mad_sat.
junyan.he at inbox.com
junyan.he at inbox.com
Thu Jan 29 03:25:00 PST 2015
From: Junyan He <junyan.he at linux.intel.com>
The bug caused because we didn't consider two overflow
cases when type is long, which do not cause carry and
are easy to be ignored.
Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
backend/src/backend/gen8_context.cpp | 35 ++++++++++++++++++++++++++++++++++-
utests/compiler_long_hi_sat.cpp | 8 ++++++--
2 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/backend/src/backend/gen8_context.cpp b/backend/src/backend/gen8_context.cpp
index cde87de..26bc50d 100644
--- a/backend/src/backend/gen8_context.cpp
+++ b/backend/src/backend/gen8_context.cpp
@@ -390,10 +390,15 @@ namespace gbe
/* saturate logic:
if(dst_h > 0)
sum = CL_LONG_MAX;
- else if(dst_h < -1)
+ else if (dst_h == 0 && sum > 0x7FFFFFFFFFFFFFFFLL) {
+ sum = CL_LONG_MAX;
+ else if (dst_h == -1 && sum < 0x8000000000000000)
+ sum = CL_LONG_MIN;
+ else (dst_h < -1)
sum = CL_LONG_MIN;
cl_long result = (cl_long) sum; */
p->MOV(dst_l, sum);
+ tmp0.type = GEN_TYPE_UL;
dst_h.type = GEN_TYPE_L;
p->push();
@@ -411,6 +416,34 @@ namespace gbe
p->curr.predicate = GEN_PREDICATE_NONE;
p->curr.noMask = 1;
p->curr.useFlag(flagReg.flag_nr(), flagReg.flag_subnr());
+ p->CMP(GEN_CONDITIONAL_EQ, dst_h, GenRegister::immd(0x0L), tmp1);
+ p->curr.noMask = 0;
+ p->curr.predicate = GEN_PREDICATE_NORMAL;
+ p->MOV(tmp0, GenRegister::immuint64(0x7FFFFFFFFFFFFFFFUL));
+ p->CMP(GEN_CONDITIONAL_G, dst_l, tmp0, tmp1);
+ p->MOV(dst_l, GenRegister::immint64(0x7FFFFFFFFFFFFFFFLL));
+ p->pop();
+ p->NOP();
+
+ p->push();
+ p->curr.predicate = GEN_PREDICATE_NONE;
+ p->curr.noMask = 1;
+ p->curr.useFlag(flagReg.flag_nr(), flagReg.flag_subnr());
+ /* Fixme: HW bug ? 0xFFFFFFFFFFFFFFFF != 0xFFFFFFFFFFFFFFFF */
+ p->ADD(tmp0, dst_h, GenRegister::immud(1));
+ p->CMP(GEN_CONDITIONAL_EQ, tmp0, GenRegister::immud(0), tmp1);
+ p->curr.noMask = 0;
+ p->curr.predicate = GEN_PREDICATE_NORMAL;
+ p->MOV(tmp0, GenRegister::immuint64(0x8000000000000000UL));
+ p->CMP(GEN_CONDITIONAL_L, dst_l, tmp0, tmp1);
+ p->MOV(dst_l, GenRegister::immint64(-0x7FFFFFFFFFFFFFFFLL - 1LL));
+ p->pop();
+ p->NOP();
+
+ p->push();
+ p->curr.predicate = GEN_PREDICATE_NONE;
+ p->curr.noMask = 1;
+ p->curr.useFlag(flagReg.flag_nr(), flagReg.flag_subnr());
p->CMP(GEN_CONDITIONAL_L, dst_h, GenRegister::immd(-1), tmp1);
p->curr.noMask = 0;
p->curr.predicate = GEN_PREDICATE_NORMAL;
diff --git a/utests/compiler_long_hi_sat.cpp b/utests/compiler_long_hi_sat.cpp
index e1d5f3b..a0f2bfa 100644
--- a/utests/compiler_long_hi_sat.cpp
+++ b/utests/compiler_long_hi_sat.cpp
@@ -57,7 +57,7 @@ static void __mad_sat(int64_t sourceA, int64_t sourceB, int64_t sourceC, int64_t
cl_long multHi;
cl_ulong multLo;
__64_mul_64(sourceA, sourceB, multLo, multHi);
-
+ //printf("hi is %lx, lo is %lx\n", multHi, multLo);
cl_ulong sum = multLo + sourceC;
// carry if overflow
@@ -82,6 +82,10 @@ static void __mad_sat(int64_t sourceA, int64_t sourceB, int64_t sourceC, int64_t
// saturate
if( multHi > 0 )
sum = CL_LONG_MAX;
+ else if ( multHi == 0 && sum > CL_LONG_MAX)
+ sum = CL_LONG_MAX;
+ else if ( multHi == -1 && sum < (cl_ulong)CL_LONG_MIN)
+ sum = CL_LONG_MIN;
else if( multHi < -1 )
sum = CL_LONG_MIN;
@@ -161,7 +165,7 @@ void compiler_long_mul_sat(void)
uint64_t a = rand();
a = a <<32 | a;
src[i] = a;
-// printf(" 0x%lx", src[i]);
+ //printf(" 0x%lx", src[i]);
}
OCL_MAP_BUFFER(0);
--
1.9.1
More information about the Beignet
mailing list