Skip to content

Commit 26d3cd1

Browse files
authored
[MoveAutoInit] Ignore unreachable basicblocks and handle catchswitch (#78232)
Fixes #78049 This patch has done: - Ignore unreachable predecessors when looking for nearest common dominator. - Check catchswitch with `getFirstNonPHI`, instead of `getFirstInsertionPt`. The latter skips EHPad.
1 parent de8f782 commit 26d3cd1

File tree

3 files changed

+104
-4
lines changed

3 files changed

+104
-4
lines changed

llvm/lib/Transforms/Utils/MoveAutoInit.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ static bool runMoveAutoInit(Function &F, DominatorTree &DT, MemorySSA &MSSA) {
164164
if (TransitiveSuccessors.count(Pred))
165165
continue;
166166

167+
if (!DT.isReachableFromEntry(Pred))
168+
continue;
169+
167170
DominatingPredecessor =
168171
DominatingPredecessor
169172
? DT.findNearestCommonDominator(DominatingPredecessor, Pred)
@@ -178,9 +181,10 @@ static bool runMoveAutoInit(Function &F, DominatorTree &DT, MemorySSA &MSSA) {
178181

179182
// CatchSwitchInst blocks can only have one instruction, so they are not
180183
// good candidates for insertion.
181-
while (isa<CatchSwitchInst>(UsersDominator->getFirstInsertionPt())) {
184+
while (isa<CatchSwitchInst>(UsersDominator->getFirstNonPHI())) {
182185
for (BasicBlock *Pred : predecessors(UsersDominator))
183-
UsersDominator = DT.findNearestCommonDominator(UsersDominator, Pred);
186+
if (DT.isReachableFromEntry(Pred))
187+
UsersDominator = DT.findNearestCommonDominator(UsersDominator, Pred);
184188
}
185189

186190
// We finally found a place where I can be moved while not introducing extra
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2+
; RUN: opt < %s -S -passes='move-auto-init' -verify-memoryssa | FileCheck %s
3+
4+
declare void @dummy()
5+
declare void @dummy1()
6+
7+
define void @test() personality ptr @dummy {
8+
; CHECK-LABEL: define void @test() personality ptr @dummy {
9+
; CHECK-NEXT: entry:
10+
; CHECK-NEXT: [[P:%.*]] = alloca [2 x i16], i32 0, align 2
11+
; CHECK-NEXT: br label [[MIDDLE:%.*]]
12+
; CHECK: middle:
13+
; CHECK-NEXT: store i32 0, ptr [[P]], align 2, !annotation [[META0:![0-9]+]]
14+
; CHECK-NEXT: [[CALL:%.*]] = invoke ptr @dummy()
15+
; CHECK-NEXT: to label [[CLEAN:%.*]] unwind label [[CATCHBB:%.*]]
16+
; CHECK: clean:
17+
; CHECK-NEXT: ret void
18+
; CHECK: catchbb:
19+
; CHECK-NEXT: [[CS:%.*]] = catchswitch within none [label [[PAD:%.*]], label %pad1] unwind to caller
20+
; CHECK: pad:
21+
; CHECK-NEXT: [[C:%.*]] = catchpad within [[CS]] [i32 0]
22+
; CHECK-NEXT: call void @dummy1()
23+
; CHECK-NEXT: ret void
24+
; CHECK: pad1:
25+
; CHECK-NEXT: [[C1:%.*]] = catchpad within [[CS]] [i32 0]
26+
; CHECK-NEXT: call void @dummy1()
27+
; CHECK-NEXT: ret void
28+
;
29+
entry:
30+
%p = alloca [2 x i16], i32 0, align 2
31+
store i32 0, ptr %p, align 2, !annotation !0
32+
br label %middle
33+
34+
middle:
35+
%call = invoke ptr @dummy() to label %clean unwind label %catchbb
36+
37+
clean:
38+
ret void
39+
40+
catchbb:
41+
%cs = catchswitch within none [label %pad, label %pad1] unwind to caller
42+
43+
pad:
44+
%c = catchpad within %cs [i32 0]
45+
call void @dummy1()
46+
ret void
47+
48+
pad1:
49+
%c1 = catchpad within %cs [i32 0]
50+
call void @dummy1()
51+
ret void
52+
}
53+
54+
!0 = !{!"auto-init"}
55+
;.
56+
; CHECK: [[META0]] = !{!"auto-init"}
57+
;.

llvm/test/Transforms/MoveAutoInit/loop.ll

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ define void @foo(i32 %x) {
77
; CHECK-LABEL: @foo(
88
; CHECK-NEXT: entry:
99
; CHECK-NEXT: [[BUFFER:%.*]] = alloca [80 x i32], align 16
10-
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[BUFFER]], i8 -86, i64 320, i1 false), !annotation !0
10+
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[BUFFER]], i8 -86, i64 320, i1 false), !annotation [[META0:![0-9]+]]
1111
; CHECK-NEXT: br label [[DO_BODY:%.*]]
1212
; CHECK: do.body:
1313
; CHECK-NEXT: [[X_ADDR_0:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ [[DEC:%.*]], [[DO_COND:%.*]] ]
@@ -53,7 +53,7 @@ define void @bar(i32 %x, i32 %y) {
5353
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[Y:%.*]], 0
5454
; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
5555
; CHECK: if.then:
56-
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[BUFFER]], i8 -86, i64 320, i1 false), !annotation !0
56+
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 16 [[BUFFER]], i8 -86, i64 320, i1 false), !annotation [[META0]]
5757
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X:%.*]], [[Y]]
5858
; CHECK-NEXT: br label [[DO_BODY:%.*]]
5959
; CHECK: do.body:
@@ -99,4 +99,43 @@ if.end: ; preds = %do.end, %entry
9999
ret void
100100
}
101101

102+
declare void @dummy()
103+
104+
define void @unreachable_pred() {
105+
; CHECK-LABEL: @unreachable_pred(
106+
; CHECK-NEXT: entry:
107+
; CHECK-NEXT: [[P:%.*]] = alloca [2 x i16], i32 0, align 2
108+
; CHECK-NEXT: store i32 0, ptr [[P]], align 2, !annotation [[META0]]
109+
; CHECK-NEXT: br i1 true, label [[LOOP:%.*]], label [[USEBB:%.*]]
110+
; CHECK: loop:
111+
; CHECK-NEXT: call void @dummy()
112+
; CHECK-NEXT: br label [[LOOP]]
113+
; CHECK: a:
114+
; CHECK-NEXT: br label [[LOOP]]
115+
; CHECK: b:
116+
; CHECK-NEXT: br label [[LOOP]]
117+
; CHECK: usebb:
118+
; CHECK-NEXT: [[USE_P:%.*]] = icmp ult ptr null, [[P]]
119+
; CHECK-NEXT: ret void
120+
;
121+
entry:
122+
%p = alloca [2 x i16], i32 0, align 2
123+
store i32 0, ptr %p, align 2, !annotation !0
124+
br i1 true, label %loop, label %usebb
125+
126+
loop:
127+
call void @dummy()
128+
br label %loop
129+
130+
a:
131+
br label %loop
132+
133+
b:
134+
br label %loop
135+
136+
usebb:
137+
%use_p = icmp ult ptr null, %p
138+
ret void
139+
}
140+
102141
!0 = !{!"auto-init"}

0 commit comments

Comments
 (0)