[Beignet] [PATCH] GBE: workaround an unsupported wide integer case.

Zhigang Gong zhigang.gong at intel.com
Tue Oct 14 19:37:07 PDT 2014


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.

This will cause an assert in current legalize pass. Before we find
out a proper way to fix this case, let's fallback to not do SROA
aggressive.

Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
 backend/src/llvm/llvm_gen_backend.cpp | 10 ++++++----
 backend/src/llvm/llvm_gen_backend.hpp |  2 +-
 backend/src/llvm/llvm_legalize.cpp    | 31 +++++++++++++++++++++++--------
 backend/src/llvm/llvm_to_gen.cpp      |  2 +-
 4 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 39e22d7..84e7ef7 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -507,10 +507,12 @@ namespace gbe
     }
 
     bool runOnFunction(Function &F) {
-     // Do not codegen any 'available_externally' functions at all, they have
-     // definitions outside the translation unit.
-     if (F.hasAvailableExternallyLinkage())
-       return false;
+      // Do not codegen any 'available_externally' functions at all, they have
+      // definitions outside the translation unit.
+      if (F.hasAvailableExternallyLinkage())
+        return false;
+      if (!unit.getValid())
+        return false;
 
       // As we inline all function calls, so skip non-kernel functions
       bool bKernel = isKernelFunction(F);
diff --git a/backend/src/llvm/llvm_gen_backend.hpp b/backend/src/llvm/llvm_gen_backend.hpp
index 35b9a75..8c8fa3c 100644
--- a/backend/src/llvm/llvm_gen_backend.hpp
+++ b/backend/src/llvm/llvm_gen_backend.hpp
@@ -94,7 +94,7 @@ namespace gbe
   llvm::ModulePass* createBarrierNodupPass(bool);
 
   /*! Legalize all wide integer instructions */
-  llvm::FunctionPass* createLegalizePass();
+  llvm::FunctionPass* createLegalizePass(ir::Unit &unit);
 
   /*! Convert the Intrinsic call to gen function */
   llvm::BasicBlockPass *createIntrinsicLoweringPass();
diff --git a/backend/src/llvm/llvm_legalize.cpp b/backend/src/llvm/llvm_legalize.cpp
index 69921ad..cec9ff6 100644
--- a/backend/src/llvm/llvm_legalize.cpp
+++ b/backend/src/llvm/llvm_legalize.cpp
@@ -39,6 +39,7 @@
 #else
 #include "llvm/Support/CFG.h"
 #endif
+#include "ir/unit.hpp"
 
 
 #include "llvm_gen_backend.hpp"
@@ -49,7 +50,7 @@ namespace gbe {
 
   class Legalize : public FunctionPass {
   public:
-    Legalize() : FunctionPass(ID) {
+    Legalize(ir::Unit &u) : FunctionPass(ID), unit(u) {
 #if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 5
       initializeDominatorTreeWrapperPassPass(*PassRegistry::getPassRegistry());
 #else
@@ -58,6 +59,8 @@ namespace gbe {
     }
     bool runOnFunction(Function& F) {
       if (!isKernelFunction(F)) return false;
+      if (!unit.getValid())
+        return false;
       return legalizeFunction(F);
     }
     void legalizeICmp(IRBuilder<> &Builder, Instruction *p);
@@ -66,7 +69,7 @@ namespace gbe {
     void legalizeAnd(IRBuilder<> &Builder, Instruction *p);
     void legalizeOr(IRBuilder<> &Builder, Instruction *p);
     void legalizeXor(IRBuilder<> &Builder, Instruction *p);
-    void legalizeBitCast(IRBuilder<> &Builder, Instruction *p);
+    bool legalizeBitCast(IRBuilder<> &Builder, Instruction *p);
     void legalizeTrunc(IRBuilder<> &Builder, Instruction *p);
     void legalizeZExt(IRBuilder<> &Builder, Instruction *p);
     bool legalizeFunction(Function& F);
@@ -77,6 +80,7 @@ namespace gbe {
     std::set<Value *> processed;
     std::map<Value *, SmallVector<Value*, 16>> valueMap;
     typedef std::map<Value*, SmallVector<Value*, 16>>::iterator ValueMapIter;
+    ir::Unit &unit;
   };
 
   void splitAPInt(APInt &data, SmallVectorImpl<APInt> &result, int totalBits, int subBits) {
@@ -394,7 +398,7 @@ namespace gbe {
     }
     valueMap.insert(std::make_pair(p, v2));
   }
-  void Legalize::legalizeBitCast(IRBuilder<> &Builder, Instruction *p) {
+  bool Legalize::legalizeBitCast(IRBuilder<> &Builder, Instruction *p) {
     SmallVector<Value*, 16> split;
     Type *dstTy = p->getType();
     Type *srcTy = dyn_cast<CastInst>(p)->getSrcTy();
@@ -415,7 +419,10 @@ namespace gbe {
       ValueMapIter iter = valueMap.find(p->getOperand(0));
       SmallVectorImpl<Value*> &opVec = iter->second;
       Type *elemTy = cast<VectorType>(dstTy)->getElementType();
-      GBE_ASSERT(elemTy == opVec[0]->getType());
+      // FIXME elemTy may be differ with opVec[0]->getType().
+      // We need to find out a better way to handle it. 
+      if (elemTy != opVec[0]->getType())
+        return false;
       Value *vec = NULL;
       Type *idxTy = IntegerType::get(p->getContext(), 32);
       for (unsigned i = 0; i < opVec.size(); ++i) {
@@ -425,8 +432,12 @@ namespace gbe {
       }
       p->replaceAllUsesWith(vec);
     } else {
-      p->dump(); GBE_ASSERT(0 && "Unsupported bitcast");
+      std::cerr << "Warning: unsupported bitcast:" << std::endl;
+      p->dump();
+      std::cerr << std::endl;
+      return false;
     }
+    return true;
   }
 
   void Legalize::legalizeTrunc(IRBuilder<> &Builder, Instruction *p) {
@@ -533,7 +544,10 @@ namespace gbe {
             break;
 
           case Instruction::BitCast:
-            legalizeBitCast(Builder, insn);
+            if (!legalizeBitCast(Builder, insn)) {
+              unit.setValid(false);
+              goto fail;
+            }
             break;
 
           case Instruction::Trunc:
@@ -559,13 +573,14 @@ namespace gbe {
       }
     }
 
+fail:
     processed.clear();
     valueMap.clear();
     return changed;
   }
 
-  FunctionPass* createLegalizePass() {
-    return new Legalize();
+  FunctionPass* createLegalizePass(ir::Unit &unit) {
+    return new Legalize(unit);
   }
   char Legalize::ID = 0;
 };
diff --git a/backend/src/llvm/llvm_to_gen.cpp b/backend/src/llvm/llvm_to_gen.cpp
index 3be4a26..dc92752 100644
--- a/backend/src/llvm/llvm_to_gen.cpp
+++ b/backend/src/llvm/llvm_to_gen.cpp
@@ -268,7 +268,7 @@ namespace gbe
       passes.add(createGVNPass());                  // Remove redundancies
     passes.add(createPrintfParserPass());
     passes.add(createScalarizePass());        // Expand all vector ops
-    passes.add(createLegalizePass());
+    passes.add(createLegalizePass(unit));
     passes.add(createDeadInstEliminationPass());  // Remove simplified instructions
     passes.add(createCFGSimplificationPass());     // Merge & remove BBs
     passes.add(createScalarizePass());        // Expand all vector ops
-- 
1.8.3.2



More information about the Beignet mailing list