diff options
author | Ryotaro Kasuga <kasuga.ryotaro@fujitsu.com> | 2025-04-03 16:21:19 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-03 16:21:19 +0900 |
commit | 91f3965be43ccb5291fcb5578b62648a1ece17bc (patch) | |
tree | 8d7587c2348bd42c9ff8971217ef8d8175100536 /llvm/lib/Transforms/Scalar/LoopInterchange.cpp | |
parent | b6c0ce0bb67d822fac1e3b42461f66c261c1157c (diff) | |
download | llvm-91f3965be43ccb5291fcb5578b62648a1ece17bc.zip llvm-91f3965be43ccb5291fcb5578b62648a1ece17bc.tar.gz llvm-91f3965be43ccb5291fcb5578b62648a1ece17bc.tar.bz2 |
[LoopInterchange] Fix the vectorizable check for a loop (#133667)
In the profitability check for vectorization, the dependency matrix was
not handled correctly. This can result to make a wrong decision: It may
say "this loop can be vectorized" when in fact it cannot. The root cause
of this is that the check process early returns when it finds '=' or 'I'
in the dependency matrix. To make sure that we can actually vectorize
the loop, we need to check all the rows of the matrix. This patch fixes
the process of checking whether we can vectorize the loop or not. Now it
won't make a wrong decision for a loop that cannot be vectorized.
Related: #131130
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LoopInterchange.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopInterchange.cpp | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp index e777f95..1dccba4cf 100644 --- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -1197,25 +1197,35 @@ LoopInterchangeProfitability::isProfitablePerInstrOrderCost() { return std::nullopt; } +/// Return true if we can vectorize the loop specified by \p LoopId. +static bool canVectorize(const CharMatrix &DepMatrix, unsigned LoopId) { + for (unsigned I = 0; I != DepMatrix.size(); I++) { + char Dir = DepMatrix[I][LoopId]; + if (Dir != 'I' && Dir != '=') + return false; + } + return true; +} + std::optional<bool> LoopInterchangeProfitability::isProfitableForVectorization( unsigned InnerLoopId, unsigned OuterLoopId, CharMatrix &DepMatrix) { - for (auto &Row : DepMatrix) { - // If the inner loop is loop independent or doesn't carry any dependency - // it is not profitable to move this to outer position, since we are - // likely able to do inner loop vectorization already. - if (Row[InnerLoopId] == 'I' || Row[InnerLoopId] == '=') - return std::optional<bool>(false); - - // If the outer loop is not loop independent it is not profitable to move - // this to inner position, since doing so would not enable inner loop - // parallelism. - if (Row[OuterLoopId] != 'I' && Row[OuterLoopId] != '=') - return std::optional<bool>(false); - } - // If inner loop has dependence and outer loop is loop independent then it - // is/ profitable to interchange to enable inner loop parallelism. - // If there are no dependences, interchanging will not improve anything. - return std::optional<bool>(!DepMatrix.empty()); + // If the outer loop is not loop independent it is not profitable to move + // this to inner position, since doing so would not enable inner loop + // parallelism. + if (!canVectorize(DepMatrix, OuterLoopId)) + return false; + + // If inner loop has dependence and outer loop is loop independent then it is + // profitable to interchange to enable inner loop parallelism. + if (!canVectorize(DepMatrix, InnerLoopId)) + return true; + + // If both the inner and the outer loop can be vectorized, it is necessary to + // check the cost of each vectorized loop for profitability decision. At this + // time we do not have a cost model to estimate them, so return nullopt. + // TODO: Estimate the cost of vectorized loop when both the outer and the + // inner loop can be vectorized. + return std::nullopt; } bool LoopInterchangeProfitability::isProfitable( |