xref: /llvm-project/llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-begin.ll (revision 0ecf7965929c4477c8b9821c68e0ad66b012d8fe)
1; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility %s | FileCheck %s
2
3target datalayout = "e-p:64:64"
4target triple = "x86_64-unknown-linux-gnu"
5
6; CHECK: [[VT1DATA:@[^ ]*]] = private constant { [8 x i8], [3 x ptr], [0 x i8] } { [8 x i8] c"\00\00\00\01\00\00\00\02", [3 x ptr] [ptr @vf0i1, ptr @vf1i1, ptr @vf1i32], [0 x i8] zeroinitializer }, section "vt1sec", !type [[T8:![0-9]+]]
7@vt1 = constant [3 x ptr] [
8ptr @vf0i1,
9ptr @vf1i1,
10ptr @vf1i32
11], section "vt1sec", !type !0
12
13; CHECK: [[VT2DATA:@[^ ]*]] = private constant { [8 x i8], [3 x ptr], [0 x i8] } { [8 x i8] c"\00\00\00\02\00\00\00\01", [3 x ptr] [ptr @vf1i1, ptr @vf0i1, ptr @vf2i32], [0 x i8] zeroinitializer }, !type [[T8]]
14@vt2 = constant [3 x ptr] [
15ptr @vf1i1,
16ptr @vf0i1,
17ptr @vf2i32
18], !type !0
19
20; CHECK: [[VT3DATA:@[^ ]*]] = private constant { [5 x i8], [3 x ptr], [0 x i8] } { [5 x i8] c"\03\00\00\00\02", [3 x ptr] [ptr @vf0i1, ptr @vf1i1, ptr @vf3i32], [0 x i8] zeroinitializer }, align 1, !type [[T5:![0-9]+]]
21@vt3 = constant [3 x ptr] [
22ptr @vf0i1,
23ptr @vf1i1,
24ptr @vf3i32
25], align 1, !type !0
26
27; CHECK: [[VT4DATA:@[^ ]*]] = private constant { [16 x i8], [3 x ptr], [0 x i8] } { [16 x i8] c"\00\00\00\00\00\00\00\00\00\00\00\04\00\00\00\01", [3 x ptr] [ptr @vf1i1, ptr @vf0i1, ptr @vf4i32], [0 x i8] zeroinitializer },  align 16, !type [[T16:![0-9]+]]
28@vt4 = constant [3 x ptr] [
29ptr @vf1i1,
30ptr @vf0i1,
31ptr @vf4i32
32], align 16, !type !0
33
34; CHECK: @vt5 = {{.*}}, !type [[T0:![0-9]+]]
35@vt5 = constant [3 x ptr] [
36ptr @__cxa_pure_virtual,
37ptr @__cxa_pure_virtual,
38ptr @__cxa_pure_virtual
39], !type !0
40
41; CHECK: @vt1 = alias [3 x ptr], getelementptr inbounds ({ [8 x i8], [3 x ptr], [0 x i8] }, ptr [[VT1DATA]], i32 0, i32 1)
42; CHECK: @vt2 = alias [3 x ptr], getelementptr inbounds ({ [8 x i8], [3 x ptr], [0 x i8] }, ptr [[VT2DATA]], i32 0, i32 1)
43; CHECK: @vt3 = alias [3 x ptr], getelementptr inbounds ({ [5 x i8], [3 x ptr], [0 x i8] }, ptr [[VT3DATA]], i32 0, i32 1)
44; CHECK: @vt4 = alias [3 x ptr], getelementptr inbounds ({ [16 x i8], [3 x ptr], [0 x i8] }, ptr [[VT4DATA]], i32 0, i32 1)
45
46define i1 @vf0i1(ptr %this) readnone {
47  ret i1 0
48}
49
50define i1 @vf1i1(ptr %this) readnone {
51  ret i1 1
52}
53
54define i32 @vf1i32(ptr %this) readnone {
55  ret i32 1
56}
57
58define i32 @vf2i32(ptr %this) readnone {
59  ret i32 2
60}
61
62define i32 @vf3i32(ptr %this) readnone {
63  ret i32 3
64}
65
66define i32 @vf4i32(ptr %this) readnone {
67  ret i32 4
68}
69
70; CHECK: define i1 @call1(
71define i1 @call1(ptr %obj) {
72  %vtable = load ptr, ptr %obj
73  %p = call i1 @llvm.type.test(ptr %vtable, metadata !"typeid")
74  call void @llvm.assume(i1 %p)
75  %fptr = load ptr, ptr %vtable
76  ; CHECK: [[VTGEP1:%[^ ]*]] = getelementptr i8, ptr %vtable, i32 -1
77  ; CHECK: [[VTLOAD1:%[^ ]*]] = load i8, ptr [[VTGEP1]]
78  ; CHECK: [[VTAND1:%[^ ]*]] = and i8 [[VTLOAD1]], 1
79  ; CHECK: [[VTCMP1:%[^ ]*]] = icmp ne i8 [[VTAND1]], 0
80  %result = call i1 %fptr(ptr %obj)
81  ; CHECK: ret i1 [[VTCMP1]]
82  ret i1 %result
83}
84
85; CHECK: define i1 @call2(
86define i1 @call2(ptr %obj) {
87  %vtable = load ptr, ptr %obj
88  %p = call i1 @llvm.type.test(ptr %vtable, metadata !"typeid")
89  call void @llvm.assume(i1 %p)
90  %fptrptr = getelementptr [3 x ptr], ptr %vtable, i32 0, i32 1
91  %fptr = load ptr, ptr %fptrptr
92  ; CHECK: [[VTGEP2:%[^ ]*]] = getelementptr i8, ptr %vtable, i32 -1
93  ; CHECK: [[VTLOAD2:%[^ ]*]] = load i8, ptr [[VTGEP2]]
94  ; CHECK: [[VTAND2:%[^ ]*]] = and i8 [[VTLOAD2]], 2
95  ; CHECK: [[VTCMP2:%[^ ]*]] = icmp ne i8 [[VTAND2]], 0
96  %result = call i1 %fptr(ptr %obj)
97  ; CHECK: ret i1 [[VTCMP2]]
98  ret i1 %result
99}
100
101; CHECK: define i32 @call3(
102define i32 @call3(ptr %obj) {
103  %vtable = load ptr, ptr %obj
104  %p = call i1 @llvm.type.test(ptr %vtable, metadata !"typeid")
105  call void @llvm.assume(i1 %p)
106  %fptrptr = getelementptr [3 x ptr], ptr %vtable, i32 0, i32 2
107  %fptr = load ptr, ptr %fptrptr
108  ; CHECK: [[VTGEP3:%[^ ]*]] = getelementptr i8, ptr %vtable, i32 -5
109  ; CHECK: [[VTLOAD3:%[^ ]*]] = load i32, ptr [[VTGEP3]]
110  %result = call i32 %fptr(ptr %obj)
111  ; CHECK: ret i32 [[VTLOAD3]]
112  ret i32 %result
113}
114
115declare i1 @llvm.type.test(ptr, metadata)
116declare void @llvm.assume(i1)
117declare void @__cxa_pure_virtual()
118
119; CHECK: [[T8]] = !{i32 8, !"typeid"}
120; CHECK: [[T5]] = !{i32 5, !"typeid"}
121; CHECK: [[T16]] = !{i32 16, !"typeid"}
122; CHECK: [[T0]] = !{i32 0, !"typeid"}
123
124!0 = !{i32 0, !"typeid"}
125