Skip to content

Commit 584e47f

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 240fe7e commit 584e47f

File tree

2 files changed

+75
-6
lines changed

2 files changed

+75
-6
lines changed

llvm/lib/Transforms/Scalar/LoopFuse.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,14 +1796,16 @@ 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. It should be done after mergeLatch()
1806+
// since merging the latches may affect the dispositions.
1807+
SE.forgetBlockAndLoopDispositions();
1808+
18071809
// Merge the loops.
18081810
SmallVector<BasicBlock *, 8> Blocks(FC1.L->blocks());
18091811
for (BasicBlock *BB : Blocks) {
@@ -2092,14 +2094,16 @@ struct LoopFuser {
20922094
// mergeLatch may remove the only block in FC1.
20932095
SE.forgetLoop(FC1.L);
20942096
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();
20982097

20992098
// Move instructions from FC0.Latch to FC1.Latch.
21002099
// Note: mergeLatch requires an updated DT.
21012100
mergeLatch(FC0, FC1);
21022101

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

0 commit comments

Comments
 (0)