From 7fbfcc653f372aed37f81ec0ca4bb2b0ee90a9f4 Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Thu, 11 May 2023 10:55:15 -0700 Subject: [PATCH] [LV/LAA] Use PSE to identify stride multiplies which simplify [mostly nfc] LV/LAA will speculate that (some) strided access patterns have unit stride, and insert runtime checks if required. LV cost models a multiply by such a stride as free. We did this by keeping around the StrideSet structure, just to check if one of the operands were one of the strides we speculated. We can instead just ask PredicatedScalarEvolution if either of the operands are one (after predicates are applied). We get mostly the same result - PSE can prove it in more cases in theory - and simpler code. --- llvm/include/llvm/Analysis/LoopAccessAnalysis.h | 6 ------ .../Vectorize/LoopVectorizationLegality.h | 2 -- llvm/lib/Analysis/LoopAccessAnalysis.cpp | 1 - llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 13 ++++++------- 4 files changed, 6 insertions(+), 16 deletions(-) diff --git a/llvm/include/llvm/Analysis/LoopAccessAnalysis.h b/llvm/include/llvm/Analysis/LoopAccessAnalysis.h index 11b4d621d764..0258285746d9 100644 --- a/llvm/include/llvm/Analysis/LoopAccessAnalysis.h +++ b/llvm/include/llvm/Analysis/LoopAccessAnalysis.h @@ -616,9 +616,6 @@ public: return SymbolicStrides; } - /// Pointer has a symbolic stride. - bool hasStride(Value *V) const { return StrideSet.count(V); } - /// Print the information about the memory accesses in the loop. void print(raw_ostream &OS, unsigned Depth = 0) const; @@ -702,9 +699,6 @@ private: /// If an access has a symbolic strides, this maps the pointer value to /// the stride symbol. DenseMap SymbolicStrides; - - /// Set of symbolic strides values. - SmallPtrSet StrideSet; }; Value *stripIntegerCast(Value *V); diff --git a/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h b/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h index 1863e2e65553..ec71eb178af1 100644 --- a/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h +++ b/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h @@ -371,8 +371,6 @@ public: return LAI->getDepChecker().getMaxSafeVectorWidthInBits(); } - bool hasStride(Value *V) { return LAI->hasStride(V); } - /// Returns true if vector representation of the instruction \p I /// requires mask. bool isMaskRequired(const Instruction *I) const { diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp index df21679e1444..358f97f83d40 100644 --- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -2758,7 +2758,6 @@ void LoopAccessInfo::collectStridedAccess(Value *MemAccess) { // SCEVUnknown as we expect. Value *StrideVal = stripIntegerCast(Stride); SymbolicStrides[Ptr] = cast(PSE->getSCEV(StrideVal)); - StrideSet.insert(Stride); } LoopAccessInfo::LoopAccessInfo(Loop *L, ScalarEvolution *SE, diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 2c27e18e2301..4727788ee090 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -6447,11 +6447,6 @@ static const SCEV *getAddressAccessSCEV( return PSE.getSCEV(Ptr); } -static bool isStrideMul(Instruction *I, LoopVectorizationLegality *Legal) { - return Legal->hasStride(I->getOperand(0)) || - Legal->hasStride(I->getOperand(1)); -} - InstructionCost LoopVectorizationCostModel::getMemInstScalarizationCost(Instruction *I, ElementCount VF) { @@ -7219,8 +7214,12 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF, case Instruction::And: case Instruction::Or: case Instruction::Xor: { - // Since we will replace the stride by 1 the multiplication should go away. - if (I->getOpcode() == Instruction::Mul && isStrideMul(I, Legal)) + // If we're speculating on the stride being 1, the multiplication may + // fold away. We can generalize this for all operations using the notion + // of neutral elements. (TODO) + if (I->getOpcode() == Instruction::Mul && + (PSE.getSCEV(I->getOperand(0))->isOne() || + PSE.getSCEV(I->getOperand(1))->isOne())) return 0; // Detect reduction patterns