[PATCH] D96708: [llvm] Bug fix: tightlyNested() of Loop interchange
Masakazu Ueno via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 15 06:26:31 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.
There is an error in the determination of whether the loop is tightly nested.
Therefore, the execution result may not be correct.
So I added a check to see if there are instructions between nested loops.
- Example
#include <stdio.h>
static long int i,j,k=3,m=3;
unsigned long int x[50];
long double a[50][50];
int main() {
for (i=0; i<50; i++) for (j=0; j<50; j++) a[i][j]=i; for (i=0; i<50; i++) x[i]=1;
j=0;
for(i=40;i>1;i--) {
k=20;
while(k++<40) x[k]=x[j]%40;
a[i][i]+=a[i][j]+a[j][i];
for(m=9;;) if (--m<5) break;
}
for (i=0; i<50; i++) for (j=0; j<50; j++)
printf("a:%ld %5.5Le \n",i,a[i][j]);
return 0;
}
*) Specified options are "-Ofast -mllvm -enable-loopinterchange=true -flegacy-pass-manager".
The difference between the results when loop interchange is enabled and disabled is shown below.
$ clang -O2 -flegacy-pass-manager -mllvm -enable-loopinterchange=true -Rpass=loop-interchange bug1362_tightlynested.c -o a_error.out
bug1362_tightlynested.c:13:3: remark: Loop interchanged with enclosing loop. [-Rpass=loop-interchange]
while(k++<40) x[k]=x[j]%40;
^
$ clang -O2 -flegacy-pass-manager -mllvm -enable-loopinterchange=false -Rpass=loop-interchange bug1362_tightlynested.c -o a_ok.out
$ ./a_error.out > a_error.res
$ ./a_ok.out > a_ok.res
$ diff a_ok.res a_error.res
103c103
< a:2 4.00000e+00
---
> a:2 4.20000e+01
154c154
< a:3 6.00000e+00
---
> a:3 6.30000e+01
205c205
< a:4 8.00000e+00
---
> a:4 8.40000e+01
:
Omit the following.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D96708
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
@@ -347,6 +347,7 @@
private:
bool tightlyNested(Loop *Outer, Loop *Inner);
+ bool containsUnsafeInstructionsInInnerLoop(void);
bool containsUnsafeInstructions(BasicBlock *BB);
/// Discover induction and reduction PHIs in the header of \p L. Induction
@@ -578,6 +579,33 @@
} // end anonymous namespace
+/// Returns true if there are unsafe instructions above or below
+/// the inner loop.
+bool LoopInterchangeLegality::containsUnsafeInstructionsInInnerLoop() {
+ BasicBlock *InnerLoopPreHeader = InnerLoop->getLoopPreheader();
+ BasicBlock *InnerLoopExit = InnerLoop->getExitBlock();
+ BasicBlock *OuterLoopHeader = OuterLoop->getHeader();
+ BasicBlock *OuterLoopLatch = OuterLoop->getLoopLatch();
+
+ // Check loop preheader.
+ if (InnerLoopPreHeader != OuterLoopHeader) {
+ for (Instruction &I : *InnerLoopPreHeader) {
+ if (!isa<BranchInst>(&I) && !isa<DbgInfoIntrinsic>(&I))
+ return true;
+ }
+ }
+ // Check loop latch
+ if (InnerLoopExit != OuterLoopLatch) {
+ for (Instruction &I : *InnerLoopExit) {
+ if (!isa<BranchInst>(&I) && !isa<PHINode>(&I) &&
+ !isa<DbgInfoIntrinsic>(&I))
+ return true;
+ }
+ }
+
+ return false;
+}
+
bool LoopInterchangeLegality::containsUnsafeInstructions(BasicBlock *BB) {
return any_of(*BB, [](const Instruction &I) {
return I.mayHaveSideEffects() || I.mayReadFromMemory();
@@ -618,6 +646,9 @@
containsUnsafeInstructions(InnerLoopPreHeader))
return false;
+ if (containsUnsafeInstructionsInInnerLoop())
+ return false;
+
LLVM_DEBUG(dbgs() << "Loops are perfectly nested\n");
// We have a perfect loop nest.
return true;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D96708.323729.patch
Type: text/x-patch
Size: 1893 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210215/2108379e/attachment.bin>
More information about the llvm-commits
mailing list