[PATCH] D96706: [llvm] Bug fix: Loop interchange for multiple loops with conditional statements
Masakazu Ueno via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 15 05:51:25 PST 2021
masakazu.ueno created this revision.
masakazu.ueno added reviewers: fhahn, hfinkel, qcolombet.
masakazu.ueno added a project: LLVM.
Herald added a subscriber: hiraditya.
masakazu.ueno requested review of this revision.
Herald added a subscriber: llvm-commits.
Loop interchange for a multiple loop containing if-statement may be performed incorrectly.
Therefore, I modified the loop interchange so that it does not optimize loops that contain conditional statements.
For example, in the following example, "-1, -1" is correct. However, if the loop is interchanged, "1, 1" is output.
#include <stdio.h>
void bar(int x[restrict 2], int a[restrict 2][2]) {
for (int i=0; i<2; ++i) {
for (int j=0; j<2; ++j) {
for (int k=0; k<2; ++k) {
if (x[j] == a[k][i]) {
x[j] = i - k;
}
}
}
}
}
int main(void) {
int x[2] = {2, 2};
int a[2][2] = {{0, 2}, {2, 0}};
bar(x, a);
printf("%d, %d\n", x[0], x[1]);
return 0;
}
Specified options are "-Ofast -mllvm -enable-loopinterchange=true -flegacy-pass-manager".
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D96706
Files:
llvm/lib/Transforms/Scalar/LoopInterchange.cpp
Index: llvm/lib/Transforms/Scalar/LoopInterchange.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -328,8 +328,8 @@
class LoopInterchangeLegality {
public:
LoopInterchangeLegality(Loop *Outer, Loop *Inner, ScalarEvolution *SE,
- OptimizationRemarkEmitter *ORE)
- : OuterLoop(Outer), InnerLoop(Inner), SE(SE), ORE(ORE) {}
+ OptimizationRemarkEmitter *ORE, DominatorTree *DT)
+ : OuterLoop(Outer), InnerLoop(Inner), SE(SE), ORE(ORE), DT(DT) {}
/// Check if the loops can be interchanged.
bool canInterchangeLoops(unsigned InnerLoopId, unsigned OuterLoopId,
@@ -347,6 +347,7 @@
private:
bool tightlyNested(Loop *Outer, Loop *Inner);
+ bool hasConditionalStatements(Loop *L);
bool containsUnsafeInstructions(BasicBlock *BB);
/// Discover induction and reduction PHIs in the header of \p L. Induction
@@ -361,6 +362,7 @@
Loop *InnerLoop;
ScalarEvolution *SE;
+ DominatorTree *DT;
/// Interface to emit optimization remarks.
OptimizationRemarkEmitter *ORE;
@@ -542,7 +544,7 @@
Loop *InnerLoop = LoopList[InnerLoopId];
Loop *OuterLoop = LoopList[OuterLoopId];
- LoopInterchangeLegality LIL(OuterLoop, InnerLoop, SE, ORE);
+ LoopInterchangeLegality LIL(OuterLoop, InnerLoop, SE, ORE, DT);
if (!LIL.canInterchangeLoops(InnerLoopId, OuterLoopId, DependencyMatrix)) {
LLVM_DEBUG(dbgs() << "Not interchanging loops. Cannot prove legality.\n");
return false;
@@ -679,6 +681,21 @@
return nullptr;
}
+/// Return true if the Loop has conditional statements.
+bool LoopInterchangeLegality::hasConditionalStatements (Loop *L) {
+ SmallVector<BasicBlock *, 4> ExitingBlocks;
+ L->getExitingBlocks(ExitingBlocks);
+
+ for (const auto BB : L->blocks()) {
+ for (BasicBlock *ExitingBlock : ExitingBlocks) {
+ if (!DT->dominates(BB, ExitingBlock)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
bool LoopInterchangeLegality::findInductionAndReductions(
Loop *L, SmallVector<PHINode *, 8> &Inductions, Loop *InnerLoop) {
if (!L->getLoopLatch() || !L->getLoopPredecessor())
@@ -760,6 +777,20 @@
return true;
}
+ if (hasConditionalStatements(InnerLoop)) {
+ LLVM_DEBUG(
+ dbgs() << "Loops including conditional statements cannot be"
+ << " interchanged.\n ");
+ ORE->emit([&]() {
+ return OptimizationRemarkMissed(DEBUG_TYPE,
+ "UnsupportedConditionalStatements",
+ InnerLoop->getStartLoc(),
+ InnerLoop->getHeader())
+ << "Loops including conditional statements cannot be interchanged.";
+ });
+ return true;
+ }
+
// TODO: Currently we handle only loops with 1 induction variable.
if (Inductions.size() != 1) {
LLVM_DEBUG(dbgs() << "Loops with more than 1 induction variables are not "
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D96706.323718.patch
Type: text/x-patch
Size: 3071 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210215/7d30fec5/attachment.bin>
More information about the llvm-commits
mailing list