[llvm] [SCEVPatternMatch] Add signed cst match; use in LV (NFC) (PR #154568)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 21 08:13:10 PDT 2025


https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/154568

>From c8ff8d17e76167ab1de9ec9092a8bd7769036c26 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Wed, 20 Aug 2025 17:04:33 +0100
Subject: [PATCH] [LV] Use SCEVPatternMatch to improve code (NFC)

The change has necessitated splitting up m_scev_SpecificInt into signed
and unsigned variants.
---
 .../Analysis/ScalarEvolutionPatternMatch.h     | 12 ++++++++++++
 .../lib/Transforms/Vectorize/LoopVectorize.cpp | 18 ++++--------------
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
index 011d5994dc670..75b2bc1c067ec 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
@@ -116,6 +116,18 @@ struct is_specific_cst {
 /// Match an SCEV constant with a plain unsigned integer.
 inline cst_pred_ty<is_specific_cst> m_scev_SpecificInt(uint64_t V) { return V; }
 
+struct is_specific_signed_cst {
+  int64_t CV;
+  is_specific_signed_cst(int64_t C) : CV(C) {}
+  bool isValue(const APInt &C) const { return C.trySExtValue() == CV; }
+};
+
+/// Match an SCEV constant with a plain signed integer (sign-extended value will
+/// be matched)
+inline cst_pred_ty<is_specific_signed_cst> m_scev_SpecificSInt(int64_t V) {
+  return V;
+}
+
 struct bind_cst_ty {
   const APInt *&CR;
 
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 7fc87a0b49f70..97c5b03a4b697 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -5918,21 +5918,11 @@ void LoopVectorizationCostModel::setVectorizedCallDecision(ElementCount VF) {
             // TODO: do we need to figure out the cost of an extract to get the
             // first lane? Or do we hope that it will be folded away?
             ScalarEvolution *SE = PSE.getSE();
-            const auto *SAR =
-                dyn_cast<SCEVAddRecExpr>(SE->getSCEV(ScalarParam));
-
-            if (!SAR || SAR->getLoop() != TheLoop) {
+            if (!match(SE->getSCEV(ScalarParam),
+                       m_scev_AffineAddRec(
+                           m_SCEV(), m_scev_SpecificSInt(Param.LinearStepOrPos),
+                           m_SpecificLoop(TheLoop))))
               ParamsOk = false;
-              break;
-            }
-
-            const SCEVConstant *Step =
-                dyn_cast<SCEVConstant>(SAR->getStepRecurrence(*SE));
-
-            if (!Step ||
-                Step->getAPInt().getSExtValue() != Param.LinearStepOrPos)
-              ParamsOk = false;
-
             break;
           }
           case VFParamKind::GlobalPredicate:



More information about the llvm-commits mailing list