Skip to content

Commit 91f3965

Browse files
authored
[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
1 parent b6c0ce0 commit 91f3965

File tree

2 files changed

+30
-23
lines changed

2 files changed

+30
-23
lines changed

llvm/lib/Transforms/Scalar/LoopInterchange.cpp

+27-17
Original file line numberDiff line numberDiff line change
@@ -1197,25 +1197,35 @@ LoopInterchangeProfitability::isProfitablePerInstrOrderCost() {
11971197
return std::nullopt;
11981198
}
11991199

1200+
/// Return true if we can vectorize the loop specified by \p LoopId.
1201+
static bool canVectorize(const CharMatrix &DepMatrix, unsigned LoopId) {
1202+
for (unsigned I = 0; I != DepMatrix.size(); I++) {
1203+
char Dir = DepMatrix[I][LoopId];
1204+
if (Dir != 'I' && Dir != '=')
1205+
return false;
1206+
}
1207+
return true;
1208+
}
1209+
12001210
std::optional<bool> LoopInterchangeProfitability::isProfitableForVectorization(
12011211
unsigned InnerLoopId, unsigned OuterLoopId, CharMatrix &DepMatrix) {
1202-
for (auto &Row : DepMatrix) {
1203-
// If the inner loop is loop independent or doesn't carry any dependency
1204-
// it is not profitable to move this to outer position, since we are
1205-
// likely able to do inner loop vectorization already.
1206-
if (Row[InnerLoopId] == 'I' || Row[InnerLoopId] == '=')
1207-
return std::optional<bool>(false);
1208-
1209-
// If the outer loop is not loop independent it is not profitable to move
1210-
// this to inner position, since doing so would not enable inner loop
1211-
// parallelism.
1212-
if (Row[OuterLoopId] != 'I' && Row[OuterLoopId] != '=')
1213-
return std::optional<bool>(false);
1214-
}
1215-
// If inner loop has dependence and outer loop is loop independent then it
1216-
// is/ profitable to interchange to enable inner loop parallelism.
1217-
// If there are no dependences, interchanging will not improve anything.
1218-
return std::optional<bool>(!DepMatrix.empty());
1212+
// If the outer loop is not loop independent it is not profitable to move
1213+
// this to inner position, since doing so would not enable inner loop
1214+
// parallelism.
1215+
if (!canVectorize(DepMatrix, OuterLoopId))
1216+
return false;
1217+
1218+
// If inner loop has dependence and outer loop is loop independent then it is
1219+
// profitable to interchange to enable inner loop parallelism.
1220+
if (!canVectorize(DepMatrix, InnerLoopId))
1221+
return true;
1222+
1223+
// If both the inner and the outer loop can be vectorized, it is necessary to
1224+
// check the cost of each vectorized loop for profitability decision. At this
1225+
// time we do not have a cost model to estimate them, so return nullopt.
1226+
// TODO: Estimate the cost of vectorized loop when both the outer and the
1227+
// inner loop can be vectorized.
1228+
return std::nullopt;
12191229
}
12201230

12211231
bool LoopInterchangeProfitability::isProfitable(

llvm/test/Transforms/LoopInterchange/profitability-vectorization-heuristic.ll

+3-6
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,13 @@
1515
; }
1616
; }
1717
;
18-
; FIXME: These loops are not exchanged at this time due to the problem in
19-
; profitability heuristic calculation for vectorization.
2018

21-
; CHECK: --- !Missed
19+
; CHECK: --- !Passed
2220
; CHECK-NEXT: Pass: loop-interchange
23-
; CHECK-NEXT: Name: InterchangeNotProfitable
21+
; CHECK-NEXT: Name: Interchanged
2422
; CHECK-NEXT: Function: interchange_necessary_for_vectorization
2523
; CHECK-NEXT: Args:
26-
; CHECK-NEXT: - String: Interchanging loops is not considered to improve cache locality nor vectorization.
27-
; CHECK-NEXT: ...
24+
; CHECK-NEXT: - String: Loop interchanged with enclosing loop.
2825
define void @interchange_necessary_for_vectorization() {
2926
entry:
3027
br label %for.i.header

0 commit comments

Comments
 (0)