diff --git a/llvm/lib/Target/X86/X86TargetTransformInfo.h b/llvm/lib/Target/X86/X86TargetTransformInfo.h --- a/llvm/lib/Target/X86/X86TargetTransformInfo.h +++ b/llvm/lib/Target/X86/X86TargetTransformInfo.h @@ -177,6 +177,10 @@ Align Alignment, TTI::TargetCostKind CostKind, const Instruction *I); + InstructionCost getPointersChainCost(ArrayRef Ptrs, + const Value *Base, + const TTI::PointersChainInfo &Info, + TTI::TargetCostKind CostKind); InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE, const SCEV *Ptr); diff --git a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp --- a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp +++ b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp @@ -4899,6 +4899,23 @@ return Cost + LT.first; } +InstructionCost X86TTIImpl::getPointersChainCost( + ArrayRef Ptrs, const Value *Base, + const TTI::PointersChainInfo &Info, TTI::TargetCostKind CostKind) { + if (Info.isSameBase() && Info.isKnownStride()) { + // If all the pointers have known stride all the differences are translated + // into constants. X86 memory addressing allows encoding it into + // displacement. So we just need to take the base GEP cost. + if (const auto *BaseGEP = dyn_cast(Base)) { + SmallVector Indices(BaseGEP->indices()); + return getGEPCost(BaseGEP->getSourceElementType(), + BaseGEP->getPointerOperand(), Indices, CostKind); + } + return TTI::TCC_Free; + } + return BaseT::getPointersChainCost(Ptrs, Base, Info, CostKind); +} + InstructionCost X86TTIImpl::getAddressComputationCost(Type *Ty, ScalarEvolution *SE, const SCEV *Ptr) { diff --git a/llvm/test/Transforms/SLPVectorizer/X86/remark_horcost.ll b/llvm/test/Transforms/SLPVectorizer/X86/remark_horcost.ll --- a/llvm/test/Transforms/SLPVectorizer/X86/remark_horcost.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/remark_horcost.ll @@ -86,7 +86,7 @@ ; YAML-NEXT: Function: foo ; YAML-NEXT: Args: ; YAML-NEXT: - String: 'Stores SLP vectorized with cost ' - ; YAML-NEXT: - Cost: '-14' + ; YAML-NEXT: - Cost: '-5' ; YAML-NEXT: - String: ' and with tree size ' ; YAML-NEXT: - TreeSize: '4' diff --git a/llvm/test/Transforms/SLPVectorizer/X86/remark_not_all_parts.ll b/llvm/test/Transforms/SLPVectorizer/X86/remark_not_all_parts.ll --- a/llvm/test/Transforms/SLPVectorizer/X86/remark_not_all_parts.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/remark_not_all_parts.ll @@ -62,7 +62,7 @@ ; YAML-NEXT: Function: foo ; YAML-NEXT: Args: ; YAML-NEXT: - String: 'Stores SLP vectorized with cost ' - ; YAML-NEXT: - Cost: '-4' + ; YAML-NEXT: - Cost: '-1' ; YAML-NEXT: - String: ' and with tree size ' ; YAML-NEXT: - TreeSize: '4'