[Beignet] [PATCH] GBE: fix a legalize pass bug when bitcast wide integer to incompaitble vector.

Yang, Rong R rong.r.yang at intel.com
Thu Oct 16 23:46:29 PDT 2014


LGTM, thanks.

-----Original Message-----
From: Beignet [mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of Zhigang Gong
Sent: Friday, October 17, 2014 12:25
To: beignet at lists.freedesktop.org
Cc: Gong, Zhigang
Subject: [Beignet] [PATCH] GBE: fix a legalize pass bug when bitcast wide integer to incompaitble vector.

Our wide integer legalize pass will assume the source type of a wide integer must be the same as the final use type. But this is not always true. The following case is a real example:

      %conv.i.i.14 = sext i8 %usrc0.i.sroa.0.14.extract.trunc to i32
      %call.i.i2.14 = tail call i32 @__gen_ocl_abs(i32 %conv.i.i.14) #5
      %conv1.i.i.14.mask = and i32 %call.i.i2.14, 255
      %uret.i.sroa.0.14.insert.ext = zext i32 %conv1.i.i.14.mask to i128
      %uret.i.sroa.0.14.insert.shift = shl nuw nsw i128 %uret.i.sroa.0.14.insert.ext, 112
      ......
      %uret.i.sroa.0.15.insert.mask = or i128 %uret.i.sroa.0.14.insert.mask.masked, %uret.i.sroa.0.14.insert.shift
      %uret.i.sroa.0.15.insert.insert = or i128 %uret.i.sroa.0.15.insert.mask, %uret.i.sroa.0.15.insert.shift
      %2 = bitcast i128 %uret.i.sroa.0.15.insert.insert to <16 x i8>

The wide integer i128 %uret.i.sroa.0.16.insert.insert is from an
i32 integer %conv1.i.i.14.mask. But the use of it is i8 vector which breaks our assumption.

According to ruiling's good suggestion, we always bitcast the wide integer to a compatible vector, take the above example:
  %3 = bitcast i128 %uret.i.sroa.0.15.insert.insert to <4 x i32> Then insert a bit cast instruction to convert it to the original destination
  %2 = bitcast <4 x i32> %3 to <16 x i8>

Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
 backend/src/llvm/llvm_legalize.cpp | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/backend/src/llvm/llvm_legalize.cpp b/backend/src/llvm/llvm_legalize.cpp
index 7a78a97..3a2cabb 100644
--- a/backend/src/llvm/llvm_legalize.cpp
+++ b/backend/src/llvm/llvm_legalize.cpp
@@ -392,6 +392,7 @@ namespace gbe {
     }
     valueMap.insert(std::make_pair(p, v2));
   }
+
   void Legalize::legalizeBitCast(IRBuilder<> &Builder, Instruction *p) {
     SmallVector<Value*, 16> split;
     Type *dstTy = p->getType();
@@ -412,16 +413,23 @@ namespace gbe {
       //bitcast from large integer to vector, so we do insertElement to build the vector
       ValueMapIter iter = valueMap.find(p->getOperand(0));
       SmallVectorImpl<Value*> &opVec = iter->second;
-      Type *elemTy = cast<VectorType>(dstTy)->getElementType();
-      GBE_ASSERT(elemTy == opVec[0]->getType());
+      Type *splitTy = opVec[0]->getType();
+      GBE_ASSERT(dstTy->getPrimitiveSizeInBits() % splitTy->getPrimitiveSizeInBits() == 0);
+      GBE_ASSERT(dstTy->getPrimitiveSizeInBits() / 
+ splitTy->getPrimitiveSizeInBits() == opVec.size());
       Value *vec = NULL;
       Type *idxTy = IntegerType::get(p->getContext(), 32);
       for (unsigned i = 0; i < opVec.size(); ++i) {
-        Value *tmp = vec ? vec : UndefValue::get(dstTy);
+        Value *tmp = vec ? vec : 
+ UndefValue::get(VectorType::get(splitTy, opVec.size()));
         Value *idx = ConstantInt::get(idxTy, i);
         vec = Builder.CreateInsertElement(tmp, opVec[i], idx);
       }
-      p->replaceAllUsesWith(vec);
+      Type *elemTy = cast<VectorType>(dstTy)->getElementType();
+      if (elemTy == opVec[0]->getType())
+        p->replaceAllUsesWith(vec);
+      else {
+        Value *newVec = Builder.CreateBitCast(vec, dstTy);
+        p->replaceAllUsesWith(newVec);
+      }
     } else {
       p->dump(); GBE_ASSERT(0 && "Unsupported bitcast");
     }
--
1.8.3.2

_______________________________________________
Beignet mailing list
Beignet at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list