Skip to content

Commit f64ee2c

Browse files
committed
add PhaseOrdering test
1 parent d8863df commit f64ee2c

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

llvm/lib/Passes/PassBuilderPipelines.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,13 @@ static cl::opt<std::string> InstrumentColdFuncOnlyPath(
305305
"with --pgo-instrument-cold-function-only)"),
306306
cl::Hidden);
307307

308+
// TODO: There is a similar flag in WPD pass, we should consolidate them by
309+
// parsing the option only once in PassBuilder and share it across both places.
310+
static cl::opt<bool> EnableDevirtualizeSpeculatively(
311+
"enable-devirtualize-speculatively",
312+
cl::desc("Enable speculative devirtualization optimization"),
313+
cl::init(false));
314+
308315
extern cl::opt<std::string> UseCtxProfile;
309316
extern cl::opt<bool> PGOInstrumentColdFunctionOnly;
310317

@@ -326,7 +333,7 @@ PipelineTuningOptions::PipelineTuningOptions() {
326333
MergeFunctions = EnableMergeFunctions;
327334
InlinerThreshold = -1;
328335
EagerlyInvalidateAnalyses = EnableEagerlyInvalidateAnalyses;
329-
DevirtualizeSpeculatively = false;
336+
DevirtualizeSpeculatively = EnableDevirtualizeSpeculatively;
330337
}
331338

332339
namespace llvm {
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
; RUN: opt -S -O3 -enable-devirtualize-speculatively %s 2>&1 | FileCheck %s
2+
3+
; Test that the devirtualized calls are inlined.
4+
5+
@vt1 = constant [1 x ptr] [ptr @vf], !type !0
6+
@vt2 = constant [1 x ptr] [ptr @vf2], !type !1
7+
8+
9+
define i1 @vf(ptr %this) {
10+
ret i1 true
11+
}
12+
13+
define i1 @vf2(ptr %this) {
14+
ret i1 false
15+
}
16+
17+
; CHECK: define i1 @call
18+
define i1 @call(ptr %obj) #1 {
19+
%vtable = load ptr, ptr %obj
20+
%p = call i1 @llvm.public.type.test(ptr %vtable, metadata !"typeid")
21+
call void @llvm.assume(i1 %p)
22+
%fptr = load ptr, ptr %vtable
23+
; if.true.direct_targ: ; preds = %0
24+
; br label %if.end.icp
25+
; if.false.orig_indirect: ; preds = %0
26+
; %res = tail call i1 %fptr(ptr nonnull %obj)
27+
; br label %if.end.icp
28+
; if.end.icp: ; preds = %if.false.orig_indirect, %if.true.direct_targ
29+
; %2 = phi i1 [ %res, %if.false.orig_indirect ], [ true, %if.true.direct_targ ]
30+
; ret i1 %2
31+
%res = call i1 %fptr(ptr %obj)
32+
ret i1 %res
33+
}
34+
35+
36+
; CHECK: define i1 @call1
37+
define i1 @call1(ptr %obj) #1 {
38+
%vtable = load ptr, ptr %obj
39+
%p = call i1 @llvm.type.test(ptr %vtable, metadata !"typeid1")
40+
call void @llvm.assume(i1 %p)
41+
%fptr = load ptr, ptr %vtable, align 8
42+
; if.true.direct_targ: ; preds = %0
43+
; br label %if.end.icp
44+
; if.false.orig_indirect: ; preds = %0
45+
; %res = tail call i1 %fptr(ptr nonnull %obj)
46+
; br label %if.end.icp
47+
; if.end.icp: ; preds = %if.false.orig_indirect, %if.true.direct_targ
48+
; %2 = phi i1 [ %res, %if.false.orig_indirect ], [ false, %if.true.direct_targ ]
49+
; ret i1 %2
50+
%res = call i1 %fptr(ptr %obj)
51+
ret i1 %res
52+
}
53+
54+
55+
declare i1 @llvm.type.test(ptr, metadata)
56+
declare i1 @llvm.public.type.test(ptr, metadata)
57+
declare void @llvm.assume(i1)
58+
59+
!0 = !{i32 0, !"typeid"}
60+
!1 = !{i32 0, !"typeid1"}

0 commit comments

Comments
 (0)