[llvm] [InstCombine] Fold icmp(constants[x]) when the range of x is given (PR #67093)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 29 01:32:38 PST 2023
================
@@ -281,40 +278,57 @@ Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
// Now that we've scanned the entire array, emit our new comparison(s). We
// order the state machines in complexity of the generated code.
- Value *Idx = GEP->getOperand(2);
-
- // If the index is larger than the pointer offset size of the target, truncate
- // the index down like the GEP would do implicitly. We don't have to do this
- // for an inbounds GEP because the index can't be out of range.
- if (!GEP->isInBounds()) {
- Type *PtrIdxTy = DL.getIndexType(GEP->getType());
- unsigned OffsetSize = PtrIdxTy->getIntegerBitWidth();
- if (Idx->getType()->getPrimitiveSizeInBits().getFixedValue() > OffsetSize)
- Idx = Builder.CreateTrunc(Idx, PtrIdxTy);
- }
- // If inbounds keyword is not present, Idx * ElementSize can overflow.
- // Let's assume that ElementSize is 2 and the wanted value is at offset 0.
+ // If inbounds keyword is not present, Idx * LongestStep can overflow.
+ // Let's assume that LongestStep is 2 and the wanted value is at offset 0.
// Then, there are two possible values for Idx to match offset 0:
// 0x00..00, 0x80..00.
// Emitting 'icmp eq Idx, 0' isn't correct in this case because the
// comparison is false if Idx was 0x80..00.
// We need to erase the highest countTrailingZeros(ElementSize) bits of Idx.
- unsigned ElementSize =
- DL.getTypeAllocSize(Init->getType()->getArrayElementType());
auto MaskIdx = [&](Value *Idx) {
- if (!GEP->isInBounds() && llvm::countr_zero(ElementSize) != 0) {
+ if (!GEP->isInBounds() && OffsetStep.countr_zero() != 0) {
Value *Mask = ConstantInt::get(Idx->getType(), -1);
- Mask = Builder.CreateLShr(Mask, llvm::countr_zero(ElementSize));
+ Mask = Builder.CreateLShr(Mask, OffsetStep.countr_zero());
Idx = Builder.CreateAnd(Idx, Mask);
}
return Idx;
};
+ // Build the index expression lazily.
+ auto LazyGetIndex = [&](Value *CurIdx) {
+ if (CurIdx)
+ return CurIdx;
+
+ // Initial bias for index. For example, when we fold cmp(GV[x + 3], C) into
+ // idx < 3, we actually get x + 3 < 3
+ Value *Idx = ConstantInt::get(
+ PtrIdxTy, (ConstantOffset - BeginOffset).sdiv(OffsetStep));
+ uint64_t IdxBitWidth = Idx->getType()->getScalarSizeInBits();
+ for (auto [Var, Coefficient] : VariableOffsets) {
----------------
dtcxzyw wrote:
The size of `VariableOffset` is 1.
https://github.com/llvm/llvm-project/pull/67093
More information about the llvm-commits
mailing list