[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