[llvm] [InstCombine] Convert load from LUT into a select (PR #98339)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 10 23:09:59 PDT 2024
================
@@ -998,6 +998,105 @@ static bool canSimplifyNullLoadOrGEP(LoadInst &LI, Value *Op) {
return false;
}
+static Value *foldLoadFromIndexedGlobal(LoadInst &LI, IRBuilderBase &Builder) {
+ if (LI.isVolatile())
+ return nullptr;
+
+ auto *GEP = dyn_cast<GetElementPtrInst>(LI.getPointerOperand());
+ if (!GEP)
+ return nullptr;
+
+ auto *GV = dyn_cast<GlobalVariable>(GEP->getPointerOperand());
+ if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer())
+ return nullptr;
+
+ Constant *Init = GV->getInitializer();
+ if (!isa<ConstantArray>(Init) && !isa<ConstantDataArray>(Init))
+ return nullptr;
+
+ Type *EltTy = Init->getType()->getArrayElementType();
+ if (EltTy != LI.getType())
+ return nullptr;
+
+ uint64_t ArrayElementCount = Init->getType()->getArrayNumElements();
+ // Don't blow up on huge arrays.
+ // This threshold is chosen based on statistics on a dataset
+ // which is collected from real-world applications.
+ constexpr uint64_t MaxArraySize = 16;
+ if (ArrayElementCount > MaxArraySize)
+ return nullptr;
+
+ auto &DL = LI.getDataLayout();
+ uint64_t IndexBW = DL.getIndexTypeSizeInBits(GEP->getType());
+ APInt ConstOffset(IndexBW, 0);
+ MapVector<Value *, APInt> VariableOffsets;
+ if (!GEP->collectOffset(DL, IndexBW, VariableOffsets, ConstOffset))
+ return nullptr;
+
+ if (!ConstOffset.isZero() || VariableOffsets.size() != 1 ||
+ VariableOffsets.front().second !=
+ DL.getTypeAllocSize(EltTy).getFixedValue())
+ return nullptr;
+
+ Value *Index = VariableOffsets.front().first;
+ if (Index->getType()->getScalarSizeInBits() != IndexBW)
+ return nullptr;
+
+ SmallMapVector<Constant *, uint64_t, 2> ValueMap;
+ // MultiMapIdx indicates that this value occurs more than once in the array.
+ constexpr uint64_t MultiMapIdx = static_cast<uint64_t>(-1);
+ uint32_t MultiMapElts = 0;
+ for (uint64_t I = 0; I < ArrayElementCount; ++I) {
+ Constant *Elt = Init->getAggregateElement(I);
+
+ // bail out if the array contains undef values
+ if (isa<UndefValue>(Elt))
+ return nullptr;
+
+ if (auto *It = ValueMap.find(Elt); It != ValueMap.end()) {
+ if (It->second == MultiMapIdx)
+ continue;
+ if (++MultiMapElts == 2)
----------------
goldsteinn wrote:
Also I know its outside the bounds of this PR, but a case that would be nice to handle is something like a character_info table. In this case there is typically a demanded bits mask which converts elts into 2 categories (and is typically seperated by something like `x + C > Thresh`).
https://github.com/llvm/llvm-project/pull/98339
More information about the llvm-commits
mailing list