aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
diff options
context:
space:
mode:
authorRyotaro Kasuga <kasuga.ryotaro@fujitsu.com>2025-03-21 21:42:49 +0900
committerGitHub <noreply@github.com>2025-03-21 21:42:49 +0900
commit281028e37ca6c97c62ba68cd43eda2ff95bc70c4 (patch)
tree03830d3586dabda28a7c315cc625126eb93aead0 /llvm/lib/Transforms/Scalar/LoopInterchange.cpp
parentea03bdee7081f25c652d581e274b10cb7c552357 (diff)
downloadllvm-281028e37ca6c97c62ba68cd43eda2ff95bc70c4.zip
llvm-281028e37ca6c97c62ba68cd43eda2ff95bc70c4.tar.gz
llvm-281028e37ca6c97c62ba68cd43eda2ff95bc70c4.tar.bz2
[LoopInterchange] Prevent from undoing its own transformation (#127473)
LoopInterchange uses the bubble-sort fashion algorithm to sort the loops in a loop nest. For two loops `A` and `B`, it calls `isProfitable(A, B)` to determine whether these loops should be exchanged. The result of `isProfitable(A, B)` should be conservative, that is, it should return true only when we are sure exchanging `A` and `B` will improve performance. If it's not conservative enough, it's possible that a subsequent `isProfitable(B, A)` will also return true, in which case LoopInterchange will undo its previous transformation. To avoid such cases, `isProfitable(B, A)` must not return true if `isProfitable(A, B)` returned true in the past. However, the current implementation can be in such a situation. This patch resolves it by correcting the handling of two loops that have the same cache cost. This resolve the problem mentioned in https://github.com/llvm/llvm-project/pull/118267#issuecomment-2510759354.
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LoopInterchange.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/LoopInterchange.cpp8
1 files changed, 3 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index 364acb0..4366418 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -1146,17 +1146,15 @@ LoopInterchangeProfitability::isProfitablePerLoopCacheAnalysis(
if (OuterLoopIt == CostMap.end())
return std::nullopt;
+ if (CC->getLoopCost(*OuterLoop) == CC->getLoopCost(*InnerLoop))
+ return std::nullopt;
unsigned InnerIndex = InnerLoopIt->second;
unsigned OuterIndex = OuterLoopIt->second;
LLVM_DEBUG(dbgs() << "InnerIndex = " << InnerIndex
<< ", OuterIndex = " << OuterIndex << "\n");
- if (InnerIndex < OuterIndex)
- return std::optional<bool>(true);
assert(InnerIndex != OuterIndex && "CostMap should assign unique "
"numbers to each loop");
- if (CC->getLoopCost(*OuterLoop) == CC->getLoopCost(*InnerLoop))
- return std::nullopt;
- return std::optional<bool>(false);
+ return std::optional<bool>(InnerIndex < OuterIndex);
}
std::optional<bool>