Skip to content

Commit 996c6b7

Browse files
committed
Add test for VFE optimization
1 parent e96e6e2 commit 996c6b7

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// compile-flags: -Zvirtual-function-elimination -Clto -O -Csymbol-mangling-version=v0
2+
3+
// CHECK: @vtable.0 = {{.*}}, !type ![[TYPE0:[0-9]+]], !vcall_visibility ![[VCALL_VIS0:[0-9]+]]
4+
// CHECK: @vtable.1 = {{.*}}, !type ![[TYPE1:[0-9]+]], !vcall_visibility ![[VCALL_VIS0:[0-9]+]]
5+
// CHECK: @vtable.2 = {{.*}}, !type ![[TYPE2:[0-9]+]], !vcall_visibility ![[VCALL_VIS2:[0-9]+]]
6+
7+
#![crate_type = "lib"]
8+
#![allow(incomplete_features)]
9+
#![feature(unsized_locals)]
10+
11+
use std::rc::Rc;
12+
13+
trait T {
14+
// CHECK-LABEL: ; <virtual_function_elimination::S as virtual_function_elimination::T>::used
15+
fn used(&self) -> i32 {
16+
1
17+
}
18+
// CHECK-LABEL: ; <virtual_function_elimination::S as virtual_function_elimination::T>::used_through_sub_trait
19+
fn used_through_sub_trait(&self) -> i32 {
20+
3
21+
}
22+
// CHECK-LABEL: ; <virtual_function_elimination::S as virtual_function_elimination::T>::by_rc
23+
fn by_rc(self: Rc<Self>) -> i32 {
24+
self.used() + self.used()
25+
}
26+
// CHECK-LABEL-NOT: {{.*}}::unused
27+
fn unused(&self) -> i32 {
28+
2
29+
}
30+
// CHECK-LABEL-NOT: {{.*}}::by_rc_unused
31+
fn by_rc_unused(self: Rc<Self>) -> i32 {
32+
self.by_rc()
33+
}
34+
}
35+
36+
trait U: T {
37+
// CHECK-LABEL: ; <virtual_function_elimination::S as virtual_function_elimination::U>::subtrait_used
38+
fn subtrait_used(&self) -> i32 {
39+
4
40+
}
41+
// CHECK-LABEL-NOT: {{.*}}::subtrait_unused
42+
fn subtrait_unused(&self) -> i32 {
43+
5
44+
}
45+
}
46+
47+
pub trait V {
48+
// CHECK-LABEL: ; <virtual_function_elimination::S as virtual_function_elimination::V>::public_function
49+
fn public_function(&self) -> i32;
50+
}
51+
52+
#[derive(Copy, Clone)]
53+
struct S;
54+
55+
impl T for S {}
56+
57+
impl U for S {}
58+
59+
impl V for S {
60+
fn public_function(&self) -> i32 {
61+
6
62+
}
63+
}
64+
65+
fn taking_t(t: &dyn T) -> i32 {
66+
// CHECK: @llvm.type.checked.load({{.*}}, i32 24, metadata !"[[MANGLED_TYPE0:[0-9a-zA-Z_]+]]")
67+
t.used()
68+
}
69+
70+
fn taking_rc_t(t: Rc<dyn T>) -> i32 {
71+
// CHECK: @llvm.type.checked.load({{.*}}, i32 40, metadata !"[[MANGLED_TYPE0:[0-9a-zA-Z_]+]]")
72+
t.by_rc()
73+
}
74+
75+
fn taking_u(u: &dyn U) -> i32 {
76+
// CHECK: @llvm.type.checked.load({{.*}}, i32 64, metadata !"[[MANGLED_TYPE1:[0-9a-zA-Z_]+]]")
77+
// CHECK: @llvm.type.checked.load({{.*}}, i32 24, metadata !"[[MANGLED_TYPE1:[0-9a-zA-Z_]+]]")
78+
// CHECK: @llvm.type.checked.load({{.*}}, i32 32, metadata !"[[MANGLED_TYPE1:[0-9a-zA-Z_]+]]")
79+
u.subtrait_used() + u.used() + u.used_through_sub_trait()
80+
}
81+
82+
pub fn taking_v(v: &dyn V) -> i32 {
83+
// CHECK: @llvm.type.checked.load({{.*}}, i32 24, metadata !"NtCsfRpWlKdQPZn_28virtual_function_elimination1V")
84+
v.public_function()
85+
}
86+
87+
pub fn main() {
88+
let s = S;
89+
taking_t(&s);
90+
taking_rc_t(Rc::new(s));
91+
taking_u(&s);
92+
taking_v(&s);
93+
}
94+
95+
// CHECK: ![[TYPE0]] = !{i64 0, !"[[MANGLED_TYPE0]]"}
96+
// CHECK: ![[VCALL_VIS0]] = !{i64 2}
97+
// CHECK: ![[TYPE1]] = !{i64 0, !"[[MANGLED_TYPE1]]"}
98+
// CHECK: ![[TYPE2]] = !{i64 0, !"NtCsfRpWlKdQPZn_28virtual_function_elimination1V"}
99+
// CHECK: ![[VCALL_VIS2]] = !{i64 1}

0 commit comments

Comments
 (0)