Skip to content

Commit 4d11955

Browse files
committed
[LoopFusion] Forget loop and block dispositions after latch merge
Merging the latches of loops may affect the dispositions, so they should be forgotten after the merge. This patch will fix the crash due to using loop dispositions after forgetting them.
1 parent ed53c41 commit 4d11955

File tree

2 files changed

+70
-6
lines changed

2 files changed

+70
-6
lines changed

llvm/lib/Transforms/Scalar/LoopFuse.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,14 +1796,15 @@ struct LoopFuser {
17961796
// mergeLatch may remove the only block in FC1.
17971797
SE.forgetLoop(FC1.L);
17981798
SE.forgetLoop(FC0.L);
1799-
// Forget block dispositions as well, so that there are no dangling
1800-
// pointers to erased/free'ed blocks.
1801-
SE.forgetBlockAndLoopDispositions();
18021799

18031800
// Move instructions from FC0.Latch to FC1.Latch.
18041801
// Note: mergeLatch requires an updated DT.
18051802
mergeLatch(FC0, FC1);
18061803

1804+
// Forget block dispositions as well, so that there are no dangling
1805+
// pointers to erased/free'ed blocks.
1806+
SE.forgetBlockAndLoopDispositions();
1807+
18071808
// Merge the loops.
18081809
SmallVector<BasicBlock *, 8> Blocks(FC1.L->blocks());
18091810
for (BasicBlock *BB : Blocks) {
@@ -2092,14 +2093,15 @@ struct LoopFuser {
20922093
// mergeLatch may remove the only block in FC1.
20932094
SE.forgetLoop(FC1.L);
20942095
SE.forgetLoop(FC0.L);
2095-
// Forget block dispositions as well, so that there are no dangling
2096-
// pointers to erased/free'ed blocks.
2097-
SE.forgetBlockAndLoopDispositions();
20982096

20992097
// Move instructions from FC0.Latch to FC1.Latch.
21002098
// Note: mergeLatch requires an updated DT.
21012099
mergeLatch(FC0, FC1);
21022100

2101+
// Forget block dispositions as well, so that there are no dangling
2102+
// pointers to erased/free'ed blocks.
2103+
SE.forgetBlockAndLoopDispositions();
2104+
21032105
// Merge the loops.
21042106
SmallVector<BasicBlock *, 8> Blocks(FC1.L->blocks());
21052107
for (BasicBlock *BB : Blocks) {
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
; RUN: opt -passes=loop-fusion -disable-output -stats < %s 2>&1 | FileCheck -check-prefix=STAT %s
2+
; STAT: 1 loop-fusion - Loops fused
3+
4+
; C Code
5+
;
6+
;; for (int i = 0; i < 100; ++i)
7+
;; Array[i][i] = -i;
8+
;; for (int row = 0; row < 100; ++row)
9+
;; for (int col = 0; col < 100; ++col)
10+
;; if (col != row)
11+
;; Array[row][col] = row + col;
12+
13+
14+
define i32 @forget_dispositions() nounwind {
15+
entry:
16+
%Array = alloca [100 x [100 x i32]], align 4
17+
br label %for.body
18+
19+
for.body: ; preds = %for.body, %entry
20+
%indvars.iv33 = phi i64 [ 0, %entry ], [ %indvars.iv.next34, %for.body ]
21+
%0 = trunc i64 %indvars.iv33 to i32
22+
%sub = sub i32 0, %0
23+
%arrayidx2 = getelementptr inbounds [100 x [100 x i32]], ptr %Array, i64 0, i64 %indvars.iv33, i64 %indvars.iv33
24+
store i32 %sub, ptr %arrayidx2, align 4
25+
%indvars.iv.next34 = add i64 %indvars.iv33, 1
26+
%lftr.wideiv35 = trunc i64 %indvars.iv.next34 to i32
27+
%exitcond36 = icmp eq i32 %lftr.wideiv35, 100
28+
br i1 %exitcond36, label %for.cond6.preheader, label %for.body
29+
30+
for.cond6.preheader: ; preds = %for.body, %for.inc17
31+
%indvars.iv29 = phi i64 [ %indvars.iv.next30, %for.inc17 ], [ 0, %for.body ]
32+
br label %for.body8
33+
34+
for.body8: ; preds = %for.inc14, %for.cond6.preheader
35+
%indvars.iv = phi i64 [ 0, %for.cond6.preheader ], [ %indvars.iv.next, %for.inc14 ]
36+
%1 = trunc i64 %indvars.iv to i32
37+
%2 = trunc i64 %indvars.iv29 to i32
38+
%cmp9 = icmp eq i32 %1, %2
39+
br i1 %cmp9, label %for.inc14, label %if.then
40+
41+
if.then: ; preds = %for.body8
42+
%3 = add i64 %indvars.iv, %indvars.iv29
43+
%arrayidx13 = getelementptr inbounds [100 x [100 x i32]], ptr %Array, i64 0, i64 %indvars.iv29, i64 %indvars.iv
44+
%4 = trunc i64 %3 to i32
45+
store i32 %4, ptr %arrayidx13, align 4
46+
br label %for.inc14
47+
48+
for.inc14: ; preds = %for.body8, %if.then
49+
%indvars.iv.next = add i64 %indvars.iv, 1
50+
%lftr.wideiv27 = trunc i64 %indvars.iv.next to i32
51+
%exitcond28 = icmp eq i32 %lftr.wideiv27, 100
52+
br i1 %exitcond28, label %for.inc17, label %for.body8
53+
54+
for.inc17: ; preds = %for.inc14
55+
%indvars.iv.next30 = add i64 %indvars.iv29, 1
56+
%lftr.wideiv31 = trunc i64 %indvars.iv.next30 to i32
57+
%exitcond32 = icmp eq i32 %lftr.wideiv31, 100
58+
br i1 %exitcond32, label %for.exit, label %for.cond6.preheader
59+
60+
for.exit: ; preds = %for.inc17
61+
ret i32 0
62+
}

0 commit comments

Comments
 (0)