[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