[llvm] [InstCombine] Fold icmp(constants[x]) when the range of x is given (PR #67093)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 22 09:40:30 PST 2023
================
@@ -110,55 +112,34 @@ static bool isSignTest(ICmpInst::Predicate &Pred, const APInt &C) {
Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
LoadInst *LI, GetElementPtrInst *GEP, GlobalVariable *GV, CmpInst &ICI,
ConstantInt *AndCst) {
- if (LI->isVolatile() || LI->getType() != GEP->getResultElementType() ||
- GV->getValueType() != GEP->getSourceElementType() ||
- !GV->isConstant() || !GV->hasDefinitiveInitializer())
+ if (LI->isVolatile() || !GV->isConstant() || !GV->hasDefinitiveInitializer())
return nullptr;
Constant *Init = GV->getInitializer();
- if (!isa<ConstantArray>(Init) && !isa<ConstantDataArray>(Init))
- return nullptr;
+ uint64_t DataSize = DL.getTypeAllocSize(Init->getType());
- uint64_t ArrayElementCount = Init->getType()->getArrayNumElements();
// Don't blow up on huge arrays.
- if (ArrayElementCount > MaxArraySizeForCombine)
- return nullptr;
-
- // There are many forms of this optimization we can handle, for now, just do
- // the simple index into a single-dimensional array.
- //
- // Require: GEP GV, 0, i {{, constant indices}}
- if (GEP->getNumOperands() < 3 ||
- !isa<ConstantInt>(GEP->getOperand(1)) ||
- !cast<ConstantInt>(GEP->getOperand(1))->isZero() ||
- isa<Constant>(GEP->getOperand(2)))
+ if (DataSize > MaxDataSizeForCombine)
return nullptr;
- // Check that indices after the variable are constants and in-range for the
- // type they index. Collect the indices. This is typically for arrays of
- // structs.
- SmallVector<unsigned, 4> LaterIndices;
+ Type *LoadedTy = LI->getType();
+ uint64_t LoadedTySize = DL.getTypeAllocSize(LoadedTy);
+ uint64_t PtrBitwidth = DL.getIndexSizeInBits(GEP->getPointerAddressSpace());
+ Type *PtrIdxTy = DL.getIndexType(GEP->getType());
- Type *EltTy = Init->getType()->getArrayElementType();
- for (unsigned i = 3, e = GEP->getNumOperands(); i != e; ++i) {
- ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand(i));
- if (!Idx) return nullptr; // Variable index.
-
- uint64_t IdxVal = Idx->getZExtValue();
- if ((unsigned)IdxVal != IdxVal) return nullptr; // Too large array index.
-
- if (StructType *STy = dyn_cast<StructType>(EltTy))
- EltTy = STy->getElementType(IdxVal);
- else if (ArrayType *ATy = dyn_cast<ArrayType>(EltTy)) {
- if (IdxVal >= ATy->getNumElements()) return nullptr;
- EltTy = ATy->getElementType();
- } else {
- return nullptr; // Unknown type.
- }
+ MapVector<Value *, APInt> VariableOffsets;
+ APInt ConstantOffset(PtrBitwidth, 0);
+ GEP->collectOffset(GEP->getModule()->getDataLayout(), PtrBitwidth,
----------------
XChy wrote:
Done.
https://github.com/llvm/llvm-project/pull/67093
More information about the llvm-commits
mailing list