diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp index 8c147ff1f7d..453503ab61d 100644 --- a/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp @@ -509,31 +509,34 @@ void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForGEP( 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; } } |

