Skip to content

Commit 4ee925e

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 1aa86ca commit 4ee925e

File tree

2 files changed

+73
-6
lines changed

2 files changed

+73
-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: 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)