summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhigang Gong <zhigang.gong@intel.com>2015-01-21 12:55:45 +0800
committerZhigang Gong <zhigang.gong@intel.com>2015-01-22 08:53:49 +0800
commit5f502770395bc3bd24882e8cb6b21efc3942692c (patch)
treefc6d62cafd9d0fcfb2aec3eafc6fa5ad1b32bf75
parent4d39af0f127f72e52e83b0b9f266c51db8875e51 (diff)
GBE: fix popcount bugs.
We need to pass correct popcount source type to backend. v2: rebase to master. Signed-off-by: Zhigang Gong <zhigang.gong@intel.com> Reviewed-by: "Luo, Xionghu" <xionghu.luo@intel.com>
-rw-r--r--backend/src/backend/gen_insn_selection.cpp10
-rw-r--r--backend/src/ir/instruction.cpp3
-rw-r--r--backend/src/libocl/tmpl/ocl_integer.tmpl.cl7
-rw-r--r--backend/src/llvm/llvm_gen_backend.cpp8
4 files changed, 18 insertions, 10 deletions
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 0e33f5d6..628fa2f1 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -2044,10 +2044,12 @@ namespace gbe
/*! Unary instruction patterns */
DECL_PATTERN(UnaryInstruction)
{
- static ir::Type getType(const ir::Opcode opcode, const ir::Type insnType) {
+ static ir::Type getType(const ir::Opcode opcode, const ir::Type insnType, bool isSrc = false) {
+ if (opcode == ir::OP_CBIT)
+ return isSrc ? insnType : ir::TYPE_U32;
if (insnType == ir::TYPE_S64 || insnType == ir::TYPE_U64 || insnType == ir::TYPE_S8 || insnType == ir::TYPE_U8)
return insnType;
- if (opcode == ir::OP_FBH || opcode == ir::OP_FBL || opcode == ir::OP_CBIT || opcode == ir::OP_LZD)
+ if (opcode == ir::OP_FBH || opcode == ir::OP_FBL || opcode == ir::OP_LZD)
return ir::TYPE_U32;
if (insnType == ir::TYPE_S16 || insnType == ir::TYPE_U16)
return insnType;
@@ -2059,8 +2061,8 @@ namespace gbe
INLINE bool emitOne(Selection::Opaque &sel, const ir::UnaryInstruction &insn, bool &markChildren) const {
const ir::Opcode opcode = insn.getOpcode();
const ir::Type insnType = insn.getType();
- const GenRegister dst = sel.selReg(insn.getDst(0), getType(opcode, insnType));
- const GenRegister src = sel.selReg(insn.getSrc(0), getType(opcode, insnType));
+ const GenRegister dst = sel.selReg(insn.getDst(0), getType(opcode, insnType, false));
+ const GenRegister src = sel.selReg(insn.getSrc(0), getType(opcode, insnType, true));
sel.push();
if (sel.isScalarReg(insn.getDst(0)) == true) {
sel.curr.execWidth = 1;
diff --git a/backend/src/ir/instruction.cpp b/backend/src/ir/instruction.cpp
index 4d1ae058..795ff079 100644
--- a/backend/src/ir/instruction.cpp
+++ b/backend/src/ir/instruction.cpp
@@ -814,7 +814,8 @@ namespace ir {
const RegisterFamily family = getFamily(this->type);
if (UNLIKELY(checkSpecialRegForWrite(dst[0], fn, whyNot) == false))
return false;
- if (UNLIKELY(checkRegisterData(family, dst[0], fn, whyNot) == false))
+ if (opcode != OP_CBIT &&
+ UNLIKELY(checkRegisterData(family, dst[0], fn, whyNot) == false))
return false;
for (uint32_t srcID = 0; srcID < srcNum; ++srcID)
if (UNLIKELY(checkRegisterData(family, src[srcID], fn, whyNot) == false))
diff --git a/backend/src/libocl/tmpl/ocl_integer.tmpl.cl b/backend/src/libocl/tmpl/ocl_integer.tmpl.cl
index 28b9c208..6da0bab2 100644
--- a/backend/src/libocl/tmpl/ocl_integer.tmpl.cl
+++ b/backend/src/libocl/tmpl/ocl_integer.tmpl.cl
@@ -19,7 +19,12 @@
PURE CONST uint __gen_ocl_fbh(uint);
PURE CONST uint __gen_ocl_fbl(uint);
-PURE CONST uint __gen_ocl_cbit(uint);
+PURE CONST OVERLOADABLE uint __gen_ocl_cbit(uint);
+PURE CONST OVERLOADABLE uint __gen_ocl_cbit(int);
+PURE CONST OVERLOADABLE uint __gen_ocl_cbit(ushort);
+PURE CONST OVERLOADABLE uint __gen_ocl_cbit(short);
+PURE CONST OVERLOADABLE uint __gen_ocl_cbit(uchar);
+PURE CONST OVERLOADABLE uint __gen_ocl_cbit(char);
OVERLOADABLE char clz(char x) {
if (x < 0)
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index ef8ce3bc..86030b9a 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -625,7 +625,7 @@ namespace gbe
#undef DECL_VISIT_FN
// Emit unary instructions from gen native function
- void emitUnaryCallInst(CallInst &I, CallSite &CS, ir::Opcode opcode);
+ void emitUnaryCallInst(CallInst &I, CallSite &CS, ir::Opcode opcode, ir::Type = ir::TYPE_FLOAT);
// Emit unary instructions from gen native function
void emitAtomicInst(CallInst &I, CallSite &CS, ir::AtomicOps opcode);
@@ -3044,7 +3044,7 @@ error:
};
}
- void GenWriter::emitUnaryCallInst(CallInst &I, CallSite &CS, ir::Opcode opcode) {
+ void GenWriter::emitUnaryCallInst(CallInst &I, CallSite &CS, ir::Opcode opcode, ir::Type type) {
CallSite::arg_iterator AI = CS.arg_begin();
#if GBE_DEBUG
CallSite::arg_iterator AE = CS.arg_end();
@@ -3052,7 +3052,7 @@ error:
GBE_ASSERT(AI != AE);
const ir::Register src = this->getRegister(*AI);
const ir::Register dst = this->getRegister(&I);
- ctx.ALU1(opcode, ir::TYPE_FLOAT, dst, src);
+ ctx.ALU1(opcode, type, dst, src);
}
void GenWriter::emitAtomicInst(CallInst &I, CallSite &CS, ir::AtomicOps opcode) {
@@ -3396,7 +3396,7 @@ error:
}
case GEN_OCL_FBH: this->emitUnaryCallInst(I,CS,ir::OP_FBH); break;
case GEN_OCL_FBL: this->emitUnaryCallInst(I,CS,ir::OP_FBL); break;
- case GEN_OCL_CBIT: this->emitUnaryCallInst(I,CS,ir::OP_CBIT); break;
+ case GEN_OCL_CBIT: this->emitUnaryCallInst(I,CS,ir::OP_CBIT, getUnsignedType(ctx, (*AI)->getType())); break;
case GEN_OCL_ABS:
{
const ir::Register src = this->getRegister(*AI);