[llvm] [SCEV] Add dedicated AffineAddRec matcher + loop matchers (NFC). (PR #141141)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Thu May 22 14:17:27 PDT 2025
https://github.com/fhahn created https://github.com/llvm/llvm-project/pull/141141
None
>From 1d8731fbc21d0f7373b6ddba64049dedc1abc0fe Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Thu, 22 May 2025 22:14:13 +0100
Subject: [PATCH] [SCEV] Add dedicated AffineAddRec matcher + loop matchers
(NFC).
---
.../Analysis/ScalarEvolutionPatternMatch.h | 41 ++++++++++++++++++-
llvm/lib/Analysis/ScalarEvolution.cpp | 10 ++---
llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 3 +-
.../Transforms/Scalar/LoopStrengthReduce.cpp | 7 ++--
4 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
index cfb1b4c6ea6b4..8e9d7e0b72142 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
@@ -196,11 +196,48 @@ m_scev_UDiv(const Op0_t &Op0, const Op1_t &Op1) {
return m_scev_Binary<SCEVUDivExpr>(Op0, Op1);
}
+inline class_match<const Loop> m_Loop() { return class_match<const Loop>(); }
+
+/// Match an affine SCEVAddRecExpr.
+template <typename Op0_t, typename Op1_t, typename Loop_t>
+struct SCEVAffineAddRec_match {
+ SCEVBinaryExpr_match<SCEVAddRecExpr, Op0_t, Op1_t> Ops;
+ Loop_t Loop;
+
+ SCEVAffineAddRec_match(Op0_t Op0, Op1_t Op1, Loop_t Loop)
+ : Ops(Op0, Op1), Loop(Loop) {}
+
+ bool match(const SCEV *S) const {
+ return Ops.match(S) && Loop.match(cast<SCEVAddRecExpr>(S)->getLoop());
+ }
+};
+
+/// Match a specified const Loop*.
+struct specificloop_ty {
+ const Loop *L;
+
+ specificloop_ty(const Loop *L) : L(L) {}
+
+ bool match(const Loop *L) const { return L == this->L; }
+};
+
+inline specificloop_ty m_SpecificLoop(const Loop *L) { return L; }
+
+inline bind_ty<const Loop> m_Loop(const Loop *&L) { return L; }
+
template <typename Op0_t, typename Op1_t>
-inline SCEVBinaryExpr_match<SCEVAddRecExpr, Op0_t, Op1_t>
+inline SCEVAffineAddRec_match<Op0_t, Op1_t, class_match<const Loop>>
m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1) {
- return m_scev_Binary<SCEVAddRecExpr>(Op0, Op1);
+ return SCEVAffineAddRec_match<Op0_t, Op1_t, class_match<const Loop>>(
+ Op0, Op1, m_Loop());
+}
+
+template <typename Op0_t, typename Op1_t, typename Loop_t>
+inline SCEVAffineAddRec_match<Op0_t, Op1_t, Loop_t>
+m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1, const Loop_t &L) {
+ return SCEVAffineAddRec_match<Op0_t, Op1_t, Loop_t>(Op0, Op1, L);
}
+
} // namespace SCEVPatternMatch
} // namespace llvm
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 5e01c29615fab..74384494c9df4 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -12531,14 +12531,14 @@ static bool IsKnownPredicateViaAddRecStart(ScalarEvolution &SE,
return false;
const SCEV *LStart, *RStart, *Step;
- if (!match(LHS, m_scev_AffineAddRec(m_SCEV(LStart), m_SCEV(Step))) ||
- !match(RHS, m_scev_AffineAddRec(m_SCEV(RStart), m_scev_Specific(Step))))
+ const Loop *L;
+ if (!match(LHS,
+ m_scev_AffineAddRec(m_SCEV(LStart), m_SCEV(Step), m_Loop(L))) ||
+ !match(RHS, m_scev_AffineAddRec(m_SCEV(RStart), m_scev_Specific(Step),
+ m_SpecificLoop(L))))
return false;
const SCEVAddRecExpr *LAR = cast<SCEVAddRecExpr>(LHS);
const SCEVAddRecExpr *RAR = cast<SCEVAddRecExpr>(RHS);
- if (LAR->getLoop() != RAR->getLoop())
- return false;
-
SCEV::NoWrapFlags NW = ICmpInst::isSigned(Pred) ?
SCEV::FlagNSW : SCEV::FlagNUW;
if (!LAR->getNoWrapFlags(NW) || !RAR->getNoWrapFlags(NW))
diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
index e774e5fd99cbb..3116b3ccd6170 100644
--- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -808,7 +808,8 @@ static bool isLoopCounter(PHINode* Phi, Loop *L,
return false;
const SCEV *S = SE->getSCEV(Phi);
- if (!match(S, m_scev_AffineAddRec(m_SCEV(), m_scev_One())) ||
+ if (!match(S,
+ m_scev_AffineAddRec(m_SCEV(), m_scev_One(), m_SpecificLoop(L))) ||
cast<SCEVAddRecExpr>(S)->getLoop() != L)
return false;
diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 1373d940f61b6..7df8d66d81af8 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -557,13 +557,14 @@ static void DoInitialMatch(const SCEV *S, Loop *L,
// Look at addrec operands.
const SCEV *Start, *Step;
- if (match(S, m_scev_AffineAddRec(m_SCEV(Start), m_SCEV(Step))) &&
+ const Loop *ARLoop;
+ if (match(S,
+ m_scev_AffineAddRec(m_SCEV(Start), m_SCEV(Step), m_Loop(ARLoop))) &&
!Start->isZero()) {
DoInitialMatch(Start, L, Good, Bad, SE);
DoInitialMatch(SE.getAddRecExpr(SE.getConstant(S->getType(), 0), Step,
// FIXME: AR->getNoWrapFlags()
- cast<SCEVAddRecExpr>(S)->getLoop(),
- SCEV::FlagAnyWrap),
+ ARLoop, SCEV::FlagAnyWrap),
L, Good, Bad, SE);
return;
}
More information about the llvm-commits
mailing list