/// Tries to compute the offset in bytes PtrB - PtrA.
std::optional<APInt> getConstantOffset(Value *PtrA, Value *PtrB,
+ Instruction *ContextInst,
unsigned Depth = 0);
- std::optional<APInt> gtConstantOffsetComplexAddrs(Value *PtrA, Value *PtrB,
- unsigned Depth);
+ std::optional<APInt> getConstantOffsetComplexAddrs(Value *PtrA, Value *PtrB,
+ Instruction *ContextInst,
+ unsigned Depth);
std::optional<APInt> getConstantOffsetSelects(Value *PtrA, Value *PtrB,
+ Instruction *ContextInst,
unsigned Depth);
/// Gets the element type of the vector that the chain will load or store.
return false;
}
-std::optional<APInt> Vectorizer::gtConstantOffsetComplexAddrs(Value *PtrA,
- Value *PtrB,
- unsigned Depth) {
- LLVM_DEBUG(dbgs() << "LSV: gtConstantOffsetComplexAddrs PtrA=" << *PtrA
- << " PtrB=" << *PtrB << " Depth=" << Depth << "\n");
+std::optional<APInt> Vectorizer::getConstantOffsetComplexAddrs(
+ Value *PtrA, Value *PtrB, Instruction *ContextInst, unsigned Depth) {
+ LLVM_DEBUG(dbgs() << "LSV: getConstantOffsetComplexAddrs PtrA=" << *PtrA
+ << " PtrB=" << *PtrB << " ContextInst=" << *ContextInst
+ << " Depth=" << Depth << "\n");
auto *GEPA = dyn_cast<GetElementPtrInst>(PtrA);
auto *GEPB = dyn_cast<GetElementPtrInst>(PtrB);
if (!GEPA || !GEPB)
- return getConstantOffsetSelects(PtrA, PtrB, Depth);
+ return getConstantOffsetSelects(PtrA, PtrB, ContextInst, Depth);
// Look through GEPs after checking they're the same except for the last
// index.
return std::nullopt;
APInt IdxDiff = *IdxDiffRange.getSingleElement();
- LLVM_DEBUG(dbgs() << "LSV: gtConstantOffsetComplexAddrs IdxDiff=" << IdxDiff
+ LLVM_DEBUG(dbgs() << "LSV: getConstantOffsetComplexAddrs IdxDiff=" << IdxDiff
<< "\n");
// Now we need to prove that adding IdxDiff to ValA won't overflow.
if (!Safe) {
// When computing known bits, use the GEPs as context instructions, since
// they likely are in the same BB as the load/store.
- Instruction *ContextInst = GEPA->comesBefore(GEPB) ? GEPB : GEPA;
KnownBits Known(BitWidth);
computeKnownBits((IdxDiff.sge(0) ? ValA : OpB), Known, DL, 0, &AC,
ContextInst, &DT);
return std::nullopt;
}
-std::optional<APInt>
-Vectorizer::getConstantOffsetSelects(Value *PtrA, Value *PtrB, unsigned Depth) {
+std::optional<APInt> Vectorizer::getConstantOffsetSelects(
+ Value *PtrA, Value *PtrB, Instruction *ContextInst, unsigned Depth) {
if (Depth++ == MaxDepth)
return std::nullopt;
if (SelectA->getCondition() != SelectB->getCondition())
return std::nullopt;
LLVM_DEBUG(dbgs() << "LSV: getConstantOffsetSelects, PtrA=" << *PtrA
- << ", PtrB=" << *PtrB << ", Depth=" << Depth << "\n");
+ << ", PtrB=" << *PtrB << ", ContextInst="
+ << *ContextInst << ", Depth=" << Depth << "\n");
std::optional<APInt> TrueDiff = getConstantOffset(
- SelectA->getTrueValue(), SelectB->getTrueValue(), Depth);
+ SelectA->getTrueValue(), SelectB->getTrueValue(), ContextInst, Depth);
if (!TrueDiff.has_value())
return std::nullopt;
- std::optional<APInt> FalseDiff = getConstantOffset(
- SelectA->getFalseValue(), SelectB->getFalseValue(), Depth);
+ std::optional<APInt> FalseDiff =
+ getConstantOffset(SelectA->getFalseValue(), SelectB->getFalseValue(),
+ ContextInst, Depth);
if (TrueDiff == FalseDiff)
return TrueDiff;
}
auto ChainIter = MRU.begin();
for (size_t J = 0; J < MaxChainsToTry && ChainIter != MRU.end();
++J, ++ChainIter) {
- std::optional<APInt> Offset =
- getConstantOffset(getLoadStorePointerOperand(ChainIter->first),
- getLoadStorePointerOperand(I));
+ std::optional<APInt> Offset = getConstantOffset(
+ getLoadStorePointerOperand(ChainIter->first),
+ getLoadStorePointerOperand(I),
+ /*ContextInst=*/
+ (ChainIter->first->comesBefore(I) ? I : ChainIter->first));
if (Offset.has_value()) {
// `Offset` might not have the expected number of bits, if e.g. AS has a
// different number of bits than opaque pointers.
}
std::optional<APInt> Vectorizer::getConstantOffset(Value *PtrA, Value *PtrB,
+ Instruction *ContextInst,
unsigned Depth) {
LLVM_DEBUG(dbgs() << "LSV: getConstantOffset, PtrA=" << *PtrA
- << ", PtrB=" << *PtrB << ", Depth=" << Depth << "\n");
+ << ", PtrB=" << *PtrB << ", ContextInst= " << *ContextInst
+ << ", Depth=" << Depth << "\n");
unsigned OffsetBitWidth = DL.getIndexTypeSizeInBits(PtrA->getType());
APInt OffsetA(OffsetBitWidth, 0);
APInt OffsetB(OffsetBitWidth, 0);
if (DistRange.isSingleElement())
return OffsetB - OffsetA + *DistRange.getSingleElement();
}
- std::optional<APInt> Diff = gtConstantOffsetComplexAddrs(PtrA, PtrB, Depth);
+ std::optional<APInt> Diff =
+ getConstantOffsetComplexAddrs(PtrA, PtrB, ContextInst, Depth);
if (Diff.has_value())
return OffsetB - OffsetA + Diff->sext(OffsetB.getBitWidth());
return std::nullopt;