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 <[email protected]> --- 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 _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet
