bool StraightLineStrengthReduce::isBasisFor(const Candidate &Basis,
const Candidate &C) {
return (Basis.Ins != C.Ins && // skip the same instruction
+ // They must have the same type too. Basis.Base == C.Base doesn't
+ // guarantee their types are the same (PR23975).
+ Basis.Ins->getType() == C.Ins->getType() &&
// Basis must dominate C in order to rewrite C with respect to Basis.
DT->dominates(Basis.Ins->getParent(), C.Ins->getParent()) &&
// They share the same base, stride, and candidate kind.
- Basis.Base == C.Base &&
- Basis.Stride == C.Stride &&
+ Basis.Base == C.Base && Basis.Stride == C.Stride &&
Basis.CandidateKind == C.CandidateKind);
}
+// TODO: use TTI->getGEPCost.
static bool isGEPFoldable(GetElementPtrInst *GEP,
const TargetTransformInfo *TTI,
const DataLayout *DL) {
BaseOffset += DL->getStructLayout(STy)->getElementOffset(Field);
}
}
+
+ unsigned AddrSpace = GEP->getPointerAddressSpace();
return TTI->isLegalAddressingMode(GEP->getType()->getElementType(), BaseGV,
- BaseOffset, HasBaseReg, Scale);
+ BaseOffset, HasBaseReg, Scale, AddrSpace);
}
// Returns whether (Base + Index * Stride) can be folded to an addressing mode.
if (GEP->getType()->isVectorTy())
return;
- const SCEV *GEPExpr = SE->getSCEV(GEP);
- Type *IntPtrTy = DL->getIntPtrType(GEP->getType());
+ SmallVector<const SCEV *, 4> IndexExprs;
+ for (auto I = GEP->idx_begin(); I != GEP->idx_end(); ++I)
+ IndexExprs.push_back(SE->getSCEV(*I));
gep_type_iterator GTI = gep_type_begin(GEP);
- for (auto I = GEP->idx_begin(); I != GEP->idx_end(); ++I) {
+ for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I) {
if (!isa<SequentialType>(*GTI++))
continue;
- Value *ArrayIdx = *I;
- // Compute the byte offset of this index.
+
+ const SCEV *OrigIndexExpr = IndexExprs[I - 1];
+ IndexExprs[I - 1] = SE->getConstant(OrigIndexExpr->getType(), 0);
+
+ // The base of this candidate is GEP's base plus the offsets of all
+ // indices except this current one.
+ const SCEV *BaseExpr = SE->getGEPExpr(GEP->getSourceElementType(),
+ SE->getSCEV(GEP->getPointerOperand()),
+ IndexExprs, GEP->isInBounds());
+ Value *ArrayIdx = GEP->getOperand(I);
uint64_t ElementSize = DL->getTypeAllocSize(*GTI);
- const SCEV *ElementSizeExpr = SE->getSizeOfExpr(IntPtrTy, *GTI);
- const SCEV *ArrayIdxExpr = SE->getSCEV(ArrayIdx);
- ArrayIdxExpr = SE->getTruncateOrSignExtend(ArrayIdxExpr, IntPtrTy);
- const SCEV *LocalOffset =
- SE->getMulExpr(ArrayIdxExpr, ElementSizeExpr, SCEV::FlagNSW);
- // The base of this candidate equals GEPExpr less the byte offset of this
- // index.
- const SCEV *Base = SE->getMinusSCEV(GEPExpr, LocalOffset);
- factorArrayIndex(ArrayIdx, Base, ElementSize, GEP);
+ factorArrayIndex(ArrayIdx, BaseExpr, ElementSize, GEP);
// When ArrayIdx is the sext of a value, we try to factor that value as
// well. Handling this case is important because array indices are
// typically sign-extended to the pointer size.
Value *TruncatedArrayIdx = nullptr;
if (match(ArrayIdx, m_SExt(m_Value(TruncatedArrayIdx))))
- factorArrayIndex(TruncatedArrayIdx, Base, ElementSize, GEP);
+ factorArrayIndex(TruncatedArrayIdx, BaseExpr, ElementSize, GEP);
+
+ IndexExprs[I - 1] = OrigIndexExpr;
}
}
// trivially dead.
RecursivelyDeleteTriviallyDeadInstructions(Bump);
} else {
+ // It's tempting to preserve nsw on Bump and/or Reduced. However, it's
+ // usually unsound, e.g.,
+ //
+ // X = (-2 +nsw 1) *nsw INT_MAX
+ // Y = (-2 +nsw 3) *nsw INT_MAX
+ // =>
+ // Y = X + 2 * INT_MAX
+ //
+ // Neither + and * in the resultant expression are nsw.
Reduced = Builder.CreateAdd(Basis.Ins, Bump);
}
break;