Skip to content

Commit a1a0e7d

Browse files
author
Elena Demikhovsky
committed
[Loop vectorizer] Simplified GEP cloning. NFC.
Simplified GEP cloning in vectorizeMemoryInstruction(). Added an assertion that checks consecutive GEP, which should have only one loop-variant operand. Differential Revision: https://reviews.llvm.org/D24557 llvm-svn: 281851
1 parent 05ee64e commit a1a0e7d

File tree

1 file changed

+26
-35
lines changed

1 file changed

+26
-35
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2783,44 +2783,35 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(Instruction *Instr) {
27832783
// Handle consecutive loads/stores.
27842784
GetElementPtrInst *Gep = getGEPInstruction(Ptr);
27852785
if (ConsecutiveStride) {
2786-
if (Gep && Legal->isInductionVariable(Gep->getPointerOperand())) {
2787-
setDebugLocFromInst(Builder, Gep);
2788-
auto *FirstBasePtr = getScalarValue(Gep->getPointerOperand(), 0, 0);
2789-
2790-
// Create the new GEP with the new induction variable.
2791-
GetElementPtrInst *Gep2 = cast<GetElementPtrInst>(Gep->clone());
2792-
Gep2->setOperand(0, FirstBasePtr);
2793-
Gep2->setName("gep.indvar.base");
2794-
Ptr = Builder.Insert(Gep2);
2795-
} else if (Gep) {
2796-
setDebugLocFromInst(Builder, Gep);
2797-
assert(PSE.getSE()->isLoopInvariant(PSE.getSCEV(Gep->getPointerOperand()),
2798-
OrigLoop) &&
2799-
"Base ptr must be invariant");
2800-
// The last index does not have to be the induction. It can be
2801-
// consecutive and be a function of the index. For example A[I+1];
2786+
if (Gep) {
28022787
unsigned NumOperands = Gep->getNumOperands();
2803-
unsigned InductionOperand = getGEPInductionOperand(Gep);
2804-
// Create the new GEP with the new induction variable.
2788+
#ifndef NDEBUG
2789+
// The original GEP that identified as a consecutive memory access
2790+
// should have only one loop-variant operand.
2791+
unsigned NumOfLoopVariantOps = 0;
2792+
for (unsigned i = 0; i < NumOperands; ++i)
2793+
if (!PSE.getSE()->isLoopInvariant(PSE.getSCEV(Gep->getOperand(i)),
2794+
OrigLoop))
2795+
NumOfLoopVariantOps++;
2796+
assert(NumOfLoopVariantOps == 1 &&
2797+
"Consecutive GEP should have only one loop-variant operand");
2798+
#endif
28052799
GetElementPtrInst *Gep2 = cast<GetElementPtrInst>(Gep->clone());
2806-
2807-
for (unsigned i = 0; i < NumOperands; ++i) {
2808-
Value *GepOperand = Gep->getOperand(i);
2809-
Instruction *GepOperandInst = dyn_cast<Instruction>(GepOperand);
2810-
2811-
// Update last index or loop invariant instruction anchored in loop.
2812-
if (i == InductionOperand ||
2813-
(GepOperandInst && OrigLoop->contains(GepOperandInst))) {
2814-
assert((i == InductionOperand ||
2815-
PSE.getSE()->isLoopInvariant(PSE.getSCEV(GepOperandInst),
2816-
OrigLoop)) &&
2817-
"Must be last index or loop invariant");
2818-
2819-
Gep2->setOperand(i, getScalarValue(GepOperand, 0, 0));
2820-
Gep2->setName("gep.indvar.idx");
2821-
}
2822-
}
2800+
Gep2->setName("gep.indvar");
2801+
2802+
// A new GEP is created for a 0-lane value of the first unroll iteration.
2803+
// The GEPs for the rest of the unroll iterations are computed below as an
2804+
// offset from this GEP.
2805+
for (unsigned i = 0; i < NumOperands; ++i)
2806+
// We can apply getScalarValue() for all GEP indices. It returns an
2807+
// original value for loop-invariant operand and 0-lane for consecutive
2808+
// operand.
2809+
Gep2->setOperand(i, getScalarValue(Gep->getOperand(i),
2810+
0, /* First unroll iteration */
2811+
0 /* 0-lane of the vector */ ));
2812+
setDebugLocFromInst(Builder, Gep);
28232813
Ptr = Builder.Insert(Gep2);
2814+
28242815
} else { // No GEP
28252816
// Use the induction element ptr.
28262817
assert(isa<PHINode>(Ptr) && "Invalid induction ptr");

0 commit comments

Comments
 (0)