[PATCH] D98263: [LoopInterchange] fix tightlyNested() in LoopInterchange legality
Congzhe Cao via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 9 21:54:23 PST 2021
congzhe added a comment.
An update: the current trunk code fails the following test (a crash as follows):
`void updateSuccessor(llvm::BranchInst*, llvm::BasicBlock*, llvm::BasicBlock*, std::vector<llvm::cfg::Update<llvm::BasicBlock*>, std::allocator<llvm::cfg::Update<llvm::BasicBlock*> > >&, bool): Assertion 'Changed && "Expected a successor to be updated"' failed.`
@A = common global [100 x [100 x i64]] zeroinitializer
@B = common global [100 x i64] zeroinitializer
;; for(int i=0;i<100;i++)
;; for(int j=0;j<100;j++)
;; A[j][i] = A[j][i]+k;
; Crashes with the newest trunk code
define void @crash(i64 %k, i64 %N, i64 signext %ny) {
entry:
br label %for1.header
for1.header:
%j23 = phi i64 [ 0, %entry ], [ %j.next24, %for1.inc10 ]
%cmp21 = icmp slt i64 0, %ny
br label %singleSucc
singleSucc:
br i1 %cmp21, label %preheader.j, label %for1.inc10
preheader.j:
br label %for2
for2:
%j = phi i64 [ %j.next, %for2 ], [ 0, %preheader.j ]
%arrayidx5 = getelementptr inbounds [100 x [100 x i64]], [100 x [100 x i64]]* @A, i64 0, i64 %j, i64 %j23
%lv = load i64, i64* %arrayidx5
%add = add nsw i64 %lv, %k
store i64 %add, i64* %arrayidx5
%j.next = add nuw nsw i64 %j, 1
%exitcond = icmp eq i64 %j, 99
br i1 %exitcond, label %for1.inc10, label %for2
for1.inc10:
%j.next24 = add nuw nsw i64 %j23, 1
%exitcond26 = icmp eq i64 %j23, 99
br i1 %exitcond26, label %for.end12, label %for1.header
for.end12:
ret void
}
The check from `LoopNest::checkLoopsStructure()` is actually more comprehensive than what was done for `tightlyNested()` in `LoopInterchange.cpp`, for example `checkLoopsStructure()` also considers the inner loop guard blocks, and some other scenarios. However, the current transformation in `LoopInterchange` may not be able to those complicated scenarios. With the previous check in `tightlyNested()` (as below) which is simpler, it would not pass legality and enter transformation, hence it would not crash.
// A perfectly nested loop will not have any branch in between the outer and
// inner block i.e. outer header will branch to either inner preheader and
// outerloop latch.
BranchInst *OuterLoopHeaderBI =
dyn_cast<BranchInst>(OuterLoopHeader->getTerminator());
if (!OuterLoopHeaderBI)
return false;
for (BasicBlock *Succ : successors(OuterLoopHeaderBI))
if (Succ != InnerLoopPreHeader && Succ != InnerLoop->getHeader() &&
Succ != OuterLoopLatch)
return false;
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D98263/new/
https://reviews.llvm.org/D98263
More information about the llvm-commits
mailing list