Changeset View
Changeset View
Standalone View
Standalone View
llvm/test/Transforms/GlobalDCE/virtual-functions-ranges.ll
- This file was moved from llvm/test/Transforms/GlobalDCE/virtual-functions-non-vfunc-entries.ll.
Show First 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | |||||
}, align 8, !type !{i64 0, !"vfunc1.type"}, !type !{i64 4, !"vfunc2.type"}, !vcall_visibility !{i64 2, i64 0, i64 8} | }, align 8, !type !{i64 0, !"vfunc1.type"}, !type !{i64 4, !"vfunc2.type"}, !vcall_visibility !{i64 2, i64 0, i64 8} | ||||
; CHECK: @vtableD = internal unnamed_addr constant { i32, i32, i8* } { | ; CHECK: @vtableD = internal unnamed_addr constant { i32, i32, i8* } { | ||||
; CHECK-SAME: i32 trunc (i64 sub (i64 ptrtoint (void ()* @vfunc1_live to i64), i64 ptrtoint ({ i32, i32, i8* }* @vtableD to i64)) to i32), | ; CHECK-SAME: i32 trunc (i64 sub (i64 ptrtoint (void ()* @vfunc1_live to i64), i64 ptrtoint ({ i32, i32, i8* }* @vtableD to i64)) to i32), | ||||
; CHECK-SAME: i32 0, | ; CHECK-SAME: i32 0, | ||||
; CHECK-SAME: i8* bitcast (void ()* @regular_non_virtual_funcD to i8*) | ; CHECK-SAME: i8* bitcast (void ()* @regular_non_virtual_funcD to i8*) | ||||
; CHECK-SAME: }, align 8 | ; CHECK-SAME: }, align 8 | ||||
; A vtable that contains multiple ranges. | |||||
@vtableE = internal unnamed_addr constant { [6 x i8*] } { [6 x i8*] [ | |||||
i8* bitcast (void ()* @regular_non_virtual_funcE1 to i8*), | |||||
i8* bitcast (void ()* @vfunc1_live to i8*), | |||||
i8* bitcast (void ()* @vfunc2_dead to i8*), | |||||
i8* bitcast (void ()* @regular_non_virtual_funcE2 to i8*), | |||||
i8* bitcast (void ()* @vfunc3_live to i8*), | |||||
i8* bitcast (void ()* @vfunc4_dead to i8*) | |||||
]}, align 8, !type !{i64 8, !"vfunc1.type"}, !type !{i64 16, !"vfunc2.type"}, !type !{i64 32, !"vfunc3.type"}, !type !{i64 40, !"vfunc4.type"}, | |||||
!vcall_visibility !{i64 2, i64 8, i64 24}, !vcall_visibility !{i64 2, i64 32, i64 48} | |||||
; CHECK: @vtableE = internal unnamed_addr constant { [6 x i8*] } { [6 x i8*] [ | |||||
; CHECK-SAME: i8* bitcast (void ()* @regular_non_virtual_funcE1 to i8*), | |||||
; CHECK-SAME: i8* bitcast (void ()* @vfunc1_live to i8*), | |||||
; CHECK-SAME: i8* null, | |||||
; CHECK-SAME: i8* bitcast (void ()* @regular_non_virtual_funcE2 to i8*), | |||||
; CHECK-SAME: i8* bitcast (void ()* @vfunc3_live to i8*), | |||||
; CHECK-SAME: i8* null | |||||
; CHECK-SAME: ] }, align 8 | |||||
; (1) vfunc1_live is referenced from @main, stays alive | ; (1) vfunc1_live is referenced from @main, stays alive | ||||
define internal void @vfunc1_live() { | define internal void @vfunc1_live() { | ||||
; CHECK: define internal void @vfunc1_live( | ; CHECK: define internal void @vfunc1_live( | ||||
ret void | ret void | ||||
} | } | ||||
; (2) vfunc2_dead is never referenced, gets removed and vtable slot is null'd | ; (2) vfunc2_dead is never referenced, gets removed and vtable slot is null'd | ||||
define internal void @vfunc2_dead() { | define internal void @vfunc2_dead() { | ||||
; CHECK-NOT: define internal void @vfunc2_dead( | ; CHECK-NOT: define internal void @vfunc2_dead( | ||||
ret void | ret void | ||||
} | } | ||||
define internal void @vfunc3_live() { | |||||
; CHECK: define internal void @vfunc3_live( | |||||
ret void | |||||
} | |||||
define internal void @vfunc4_dead() { | |||||
; CHECK-NOT: define internal void @vfunc4_dead( | |||||
ret void | |||||
} | |||||
; (3) not using a range in !vcall_visibility, global gets removed | ; (3) not using a range in !vcall_visibility, global gets removed | ||||
define internal void @regular_non_virtual_funcA() { | define internal void @regular_non_virtual_funcA() { | ||||
; CHECK-NOT: define internal void @regular_non_virtual_funcA( | ; CHECK-NOT: define internal void @regular_non_virtual_funcA( | ||||
ret void | ret void | ||||
} | } | ||||
; (4) using a range in !vcall_visibility, pointer is outside of range, so should | ; (4) using a range in !vcall_visibility, pointer is outside of range, so should | ||||
; stay alive | ; stay alive | ||||
Show All 11 Lines | |||||
; (6) using a range in !vcall_visibility, pointer is outside of range, so should | ; (6) using a range in !vcall_visibility, pointer is outside of range, so should | ||||
; stay alive | ; stay alive | ||||
define internal void @regular_non_virtual_funcD() { | define internal void @regular_non_virtual_funcD() { | ||||
; CHECK: define internal void @regular_non_virtual_funcD( | ; CHECK: define internal void @regular_non_virtual_funcD( | ||||
ret void | ret void | ||||
} | } | ||||
define internal void @regular_non_virtual_funcE1() { | |||||
; CHECK: define internal void @regular_non_virtual_funcE1( | |||||
ret void | |||||
} | |||||
define internal void @regular_non_virtual_funcE2() { | |||||
; CHECK: define internal void @regular_non_virtual_funcE2( | |||||
ret void | |||||
} | |||||
define void @main() { | define void @main() { | ||||
%1 = ptrtoint { [3 x i8*] }* @vtableA to i64 ; to keep @vtableA alive | %1 = ptrtoint { [3 x i8*] }* @vtableA to i64 ; to keep @vtableA alive | ||||
%2 = ptrtoint { [3 x i8*] }* @vtableB to i64 ; to keep @vtableB alive | %2 = ptrtoint { [3 x i8*] }* @vtableB to i64 ; to keep @vtableB alive | ||||
%3 = ptrtoint { [3 x i8*] }* @vtableC to i64 ; to keep @vtableC alive | %3 = ptrtoint { [3 x i8*] }* @vtableC to i64 ; to keep @vtableC alive | ||||
%4 = ptrtoint { i32, i32, i8* }* @vtableD to i64 ; to keep @vtableD alive | %4 = ptrtoint { i32, i32, i8* }* @vtableD to i64 ; to keep @vtableD alive | ||||
%5 = tail call { i8*, i1 } @llvm.type.checked.load(i8* null, i32 0, metadata !"vfunc1.type") | %5 = ptrtoint { [6 x i8*] }* @vtableE to i64 ; to keep @vtableE alive | ||||
%6 = tail call { i8*, i1 } @llvm.type.checked.load(i8* null, i32 0, metadata !"vfunc1.type") | |||||
%7 = tail call { i8*, i1 } @llvm.type.checked.load(i8* null, i32 0, metadata !"vfunc3.type") | |||||
ret void | ret void | ||||
} | } | ||||
!999 = !{i32 1, !"Virtual Function Elim", i32 1} | !999 = !{i32 1, !"Virtual Function Elim", i32 1} | ||||
!llvm.module.flags = !{!999} | !llvm.module.flags = !{!999} |