
This patch is to resolve the bug reported and discussed in https://reviews.llvm.org/D124926#3718761 and https://reviews.llvm.org/D124926#3719876. The problem is that loop interchange is a loopnest pass under the new pass manager, but the loop nest may not be constructed correctly by the loop pass manager after running loop interchange and before running the next pass, which might cause problems when it continues running the next pass. The reason that the loop nest is constructed incorrectly is that the outermost loop might have changed after interchange, and what was the original outermost loop is not the current outermost loop anymore. Constructing the loop nest based on the original outermost loop would generate an invalid loop nest. The fix in this patch is that, in the loop pass manager before running each loopnest pass, we re-cosntruct the loop nest based on the current outermost loop, if LPMUpdater notifies the loop pass manager that the previous loop nest has been invalidated by passes like loop interchange. Reviewed By: aeubanks Differential Revision: https://reviews.llvm.org/D132199
54 lines
2.5 KiB
LLVM
54 lines
2.5 KiB
LLVM
; REQUIRES: asserts
|
|
; RUN: opt < %s -passes="loop(loop-interchange,loop-interchange)" -cache-line-size=8 -verify-dom-info -verify-loop-info \
|
|
; RUN: -debug-only=loop-interchange 2>&1 | FileCheck %s
|
|
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
@g_75 = external global i32, align 1
|
|
@g_78 = external global [6 x ptr], align 1
|
|
|
|
; Loop interchange as a loopnest pass should always construct the loop nest from
|
|
; the outermost loop. This test case runs loop interchange twice. In the loop pass
|
|
; manager, it might occur that after the first loop interchange transformation
|
|
; the original outermost loop becomes a inner loop hence the loop nest constructed
|
|
; afterwards for the second loop interchange pass turns out to be a loop list of size
|
|
; 2 and is not valid. This causes functional issues.
|
|
;
|
|
; Make sure we always construct the valid and correct loop nest at the beginning
|
|
; of execution of a loopnest pass.
|
|
|
|
; CHECK: Processing LoopList of size = 3
|
|
; CHECK: Processing LoopList of size = 3
|
|
define void @loopnest_01() {
|
|
entry:
|
|
br label %for.cond5.preheader.i.i.i
|
|
|
|
for.cond5.preheader.i.i.i: ; preds = %for.end16.i.i.i, %entry
|
|
%storemerge11.i.i.i = phi i32 [ 4, %entry ], [ %sub18.i.i.i, %for.end16.i.i.i ]
|
|
br label %for.cond8.preheader.i.i.i
|
|
|
|
for.cond8.preheader.i.i.i: ; preds = %for.inc14.i.i.i, %for.cond5.preheader.i.i.i
|
|
%l_105.18.i.i.i = phi i16 [ 0, %for.cond5.preheader.i.i.i ], [ %add15.i.i.i, %for.inc14.i.i.i ]
|
|
br label %for.body10.i.i.i
|
|
|
|
for.body10.i.i.i: ; preds = %for.body10.i.i.i, %for.cond8.preheader.i.i.i
|
|
%storemerge56.i.i.i = phi i16 [ 5, %for.cond8.preheader.i.i.i ], [ %sub.i.i.i, %for.body10.i.i.i ]
|
|
%arrayidx.i.i.i = getelementptr [6 x ptr], ptr @g_78, i16 0, i16 %storemerge56.i.i.i
|
|
store ptr @g_75, ptr %arrayidx.i.i.i, align 1
|
|
%sub.i.i.i = add nsw i16 %storemerge56.i.i.i, -1
|
|
br i1 true, label %for.inc14.i.i.i, label %for.body10.i.i.i
|
|
|
|
for.inc14.i.i.i: ; preds = %for.body10.i.i.i
|
|
%add15.i.i.i = add nuw nsw i16 %l_105.18.i.i.i, 1
|
|
%exitcond.not.i.i.i = icmp eq i16 %add15.i.i.i, 6
|
|
br i1 %exitcond.not.i.i.i, label %for.end16.i.i.i, label %for.cond8.preheader.i.i.i
|
|
|
|
for.end16.i.i.i: ; preds = %for.inc14.i.i.i
|
|
%sub18.i.i.i = add nsw i32 %storemerge11.i.i.i, -1
|
|
%cmp.i10.not.i.i = icmp eq i32 %storemerge11.i.i.i, 0
|
|
br i1 %cmp.i10.not.i.i, label %func_4.exit.i, label %for.cond5.preheader.i.i.i
|
|
|
|
func_4.exit.i: ; preds = %for.end16.i.i.i
|
|
unreachable
|
|
}
|