[Beignet] [PATCH 4/8] Backend: Add half float support in gen backend.
junyan.he at inbox.com
junyan.he at inbox.com
Thu May 21 01:25:45 PDT 2015
From: Junyan He <junyan.he at linux.intel.com>
Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
backend/src/llvm/llvm_gen_backend.cpp | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 61b66b6..5c4f17c 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -154,6 +154,7 @@
#include "llvm/llvm_gen_backend.hpp"
#include "ir/context.hpp"
#include "ir/unit.hpp"
+#include "ir/half.hpp"
#include "ir/liveness.hpp"
#include "ir/value.hpp"
#include "sys/set.hpp"
@@ -182,6 +183,7 @@ namespace gbe
static bool isScalarType(const Type *type)
{
return type->isFloatTy() ||
+ type->isHalfTy() ||
type->isIntegerTy() ||
type->isDoubleTy() ||
type->isPointerTy();
@@ -193,6 +195,8 @@ namespace gbe
GBE_ASSERT(isScalarType(type));
if (type->isFloatTy() == true)
return ir::TYPE_FLOAT;
+ if (type->isHalfTy() == true)
+ return ir::TYPE_HALF;
if (type->isDoubleTy() == true)
return ir::TYPE_DOUBLE;
if (type->isPointerTy() == true) {
@@ -241,7 +245,7 @@ namespace gbe
return ir::FAMILY_BOOL;
if (type == Type::getInt8Ty(type->getContext()))
return ir::FAMILY_BYTE;
- if (type == Type::getInt16Ty(type->getContext()))
+ if (type == Type::getInt16Ty(type->getContext()) || type->isHalfTy())
return ir::FAMILY_WORD;
if (type == Type::getInt32Ty(type->getContext()) || type->isFloatTy())
return ir::FAMILY_DWORD;
@@ -361,6 +365,7 @@ namespace gbe
switch (typeID) {
case Type::IntegerTyID:
case Type::FloatTyID:
+ case Type::HalfTyID:
case Type::DoubleTyID:
case Type::PointerTyID:
GBE_ASSERT(index == 0);
@@ -373,6 +378,7 @@ namespace gbe
auto elementTypeID = elementType->getTypeID();
if (elementTypeID != Type::IntegerTyID &&
elementTypeID != Type::FloatTyID &&
+ elementTypeID != Type::HalfTyID &&
elementTypeID != Type::DoubleTyID)
GBE_ASSERTM(false, "Vectors of elements are not supported");
return this->_newScalar(value, key, elementType, index, uniform);
@@ -385,6 +391,7 @@ namespace gbe
auto elementTypeID = elementType->getTypeID();
if (elementTypeID != Type::IntegerTyID &&
elementTypeID != Type::FloatTyID &&
+ elementTypeID != Type::HalfTyID &&
elementTypeID != Type::DoubleTyID)
GBE_ASSERTM(false, "Strcuts of elements are not supported");
return this->_newScalar(value, key, elementType, index, uniform);
@@ -942,6 +949,8 @@ namespace gbe
return processSeqConstant<float>(seq, index, CONST_FLOAT);
} else if (Ty == Type::getDoubleTy(CPV->getContext())) {
return processSeqConstant<double>(seq, index, CONST_DOUBLE);
+ } else if (Ty == Type::getHalfTy(CPV->getContext())) {
+ GBE_ASSERTM(0, "Const data array never be half float\n");
}
} else
#endif /* LLVM_VERSION_MINOR > 0 */
@@ -968,6 +977,9 @@ namespace gbe
} else if (Ty == Type::getFloatTy(CPV->getContext())) {
const float f32 = 0;
return ctx.newImmediate(f32);
+ } else if (Ty == Type::getHalfTy(CPV->getContext())) {
+ const ir::half f16 = 0;
+ return ctx.newImmediate(f16);
} else if (Ty == Type::getDoubleTy(CPV->getContext())) {
const double f64 = 0;
return ctx.newImmediate(f64);
@@ -1021,6 +1033,7 @@ namespace gbe
if (Ty == Type::getInt32Ty(CPV->getContext())) return ctx.newImmediate((uint32_t)0);
if (Ty == Type::getInt64Ty(CPV->getContext())) return ctx.newImmediate((uint64_t)0);
if (Ty == Type::getFloatTy(CPV->getContext())) return ctx.newImmediate((float)0);
+ if (Ty == Type::getHalfTy(CPV->getContext())) return ctx.newImmediate((ir::half)0);
if (Ty == Type::getDoubleTy(CPV->getContext())) return ctx.newImmediate((double)0);
GBE_ASSERT(0 && "Unsupported undef value type.\n");
}
@@ -1028,6 +1041,7 @@ namespace gbe
// Floats and doubles
switch (typeID) {
case Type::FloatTyID:
+ case Type::HalfTyID:
case Type::DoubleTyID:
{
ConstantFP *FPC = cast<ConstantFP>(CPV);
@@ -1036,9 +1050,16 @@ namespace gbe
if (FPC->getType() == Type::getFloatTy(CPV->getContext())) {
const float f32 = FPC->getValueAPF().convertToFloat();
return ctx.newImmediate(f32);
- } else {
+ } else if (FPC->getType() == Type::getDoubleTy(CPV->getContext())) {
const double f64 = FPC->getValueAPF().convertToDouble();
return ctx.newImmediate(f64);
+ } else {
+ llvm::APFloat apf = FPC->getValueAPF();
+ llvm::APInt api = apf.bitcastToAPInt();
+ uint64_t v64 = api.getZExtValue();
+ uint16_t v16 = static_cast<uint16_t>(v64);
+ const ir::half f16(v16);
+ return ctx.newImmediate(f16);
}
}
break;
@@ -1075,6 +1096,7 @@ namespace gbe
switch (typeID) {
case Type::IntegerTyID:
case Type::FloatTyID:
+ case Type::HalfTyID:
case Type::DoubleTyID:
case Type::PointerTyID:
regTranslator.newScalar(value, key, 0, uniform);
--
1.9.1
More information about the Beignet
mailing list