blob: b39e7bc0f7f2b711e1bf0c7b80daedfa71fb18bf [file] [log] [blame]
Dan Gohman7d7409e2017-02-28 23:37:04 +00001; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=TYPEINFONAME
2; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=VTABLE
3; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=TYPEINFO
JF Bastien374ea4b2015-12-19 18:55:18 +00004
5; Test that simple vtables assemble as expected.
6;
7; The class hierarchy is:
8; struct A;
9; struct B : public A;
10; struct C : public A;
11; struct D : public B;
12; Each with a virtual dtor and method foo.
13
Dan Gohman0c6f5ac2016-01-07 03:19:23 +000014target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
Dan Gohman7d7409e2017-02-28 23:37:04 +000015target triple = "wasm32-unknown-unknown-wasm"
JF Bastien374ea4b2015-12-19 18:55:18 +000016
17%struct.A = type { i32 (...)** }
18%struct.B = type { %struct.A }
19%struct.C = type { %struct.A }
20%struct.D = type { %struct.B }
21
22@_ZTVN10__cxxabiv117__class_type_infoE = external global i8*
23@_ZTVN10__cxxabiv120__si_class_type_infoE = external global i8*
24
25; TYPEINFONAME-LABEL: _ZTS1A:
26; TYPEINFONAME-NEXT: .asciz "1A"
27@_ZTS1A = constant [3 x i8] c"1A\00"
28; TYPEINFONAME-LABEL: _ZTS1B:
29; TYPEINFONAME-NEXT: .asciz "1B"
30@_ZTS1B = constant [3 x i8] c"1B\00"
31; TYPEINFONAME-LABEL: _ZTS1C:
32; TYPEINFONAME-NEXT: .asciz "1C"
33@_ZTS1C = constant [3 x i8] c"1C\00"
34; TYPEINFONAME-LABEL: _ZTS1D:
35; TYPEINFONAME-NEXT: .asciz "1D"
36@_ZTS1D = constant [3 x i8] c"1D\00"
37
38; VTABLE: .type _ZTV1A,@object
Dan Gohman7d7409e2017-02-28 23:37:04 +000039; VTABLE-NEXT: .section .data.rel.ro._ZTV1A,
JF Bastien374ea4b2015-12-19 18:55:18 +000040; VTABLE-NEXT: .globl _ZTV1A
41; VTABLE-LABEL: _ZTV1A:
42; VTABLE-NEXT: .int32 0
43; VTABLE-NEXT: .int32 _ZTI1A
44; VTABLE-NEXT: .int32 _ZN1AD2Ev
45; VTABLE-NEXT: .int32 _ZN1AD0Ev
46; VTABLE-NEXT: .int32 _ZN1A3fooEv
47; VTABLE-NEXT: .size _ZTV1A, 20
48@_ZTV1A = constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (%struct.A* (%struct.A*)* @_ZN1AD2Ev to i8*), i8* bitcast (void (%struct.A*)* @_ZN1AD0Ev to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A3fooEv to i8*)], align 4
49; VTABLE: .type _ZTV1B,@object
Dan Gohman7d7409e2017-02-28 23:37:04 +000050; VTABLE-NEXT: .section .data.rel.ro._ZTV1B,
JF Bastien374ea4b2015-12-19 18:55:18 +000051; VTABLE-NEXT: .globl _ZTV1B
52; VTABLE-LABEL: _ZTV1B:
53; VTABLE-NEXT: .int32 0
54; VTABLE-NEXT: .int32 _ZTI1B
55; VTABLE-NEXT: .int32 _ZN1AD2Ev
56; VTABLE-NEXT: .int32 _ZN1BD0Ev
57; VTABLE-NEXT: .int32 _ZN1B3fooEv
58; VTABLE-NEXT: .size _ZTV1B, 20
59@_ZTV1B = constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1B to i8*), i8* bitcast (%struct.A* (%struct.A*)* @_ZN1AD2Ev to i8*), i8* bitcast (void (%struct.B*)* @_ZN1BD0Ev to i8*), i8* bitcast (void (%struct.B*)* @_ZN1B3fooEv to i8*)], align 4
60; VTABLE: .type _ZTV1C,@object
Dan Gohman7d7409e2017-02-28 23:37:04 +000061; VTABLE-NEXT: .section .data.rel.ro._ZTV1C,
JF Bastien374ea4b2015-12-19 18:55:18 +000062; VTABLE-NEXT: .globl _ZTV1C
63; VTABLE-LABEL: _ZTV1C:
64; VTABLE-NEXT: .int32 0
65; VTABLE-NEXT: .int32 _ZTI1C
66; VTABLE-NEXT: .int32 _ZN1AD2Ev
67; VTABLE-NEXT: .int32 _ZN1CD0Ev
68; VTABLE-NEXT: .int32 _ZN1C3fooEv
69; VTABLE-NEXT: .size _ZTV1C, 20
70@_ZTV1C = constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1C to i8*), i8* bitcast (%struct.A* (%struct.A*)* @_ZN1AD2Ev to i8*), i8* bitcast (void (%struct.C*)* @_ZN1CD0Ev to i8*), i8* bitcast (void (%struct.C*)* @_ZN1C3fooEv to i8*)], align 4
71; VTABLE: .type _ZTV1D,@object
Dan Gohman7d7409e2017-02-28 23:37:04 +000072; VTABLE-NEXT: .section .data.rel.ro._ZTV1D,
JF Bastien374ea4b2015-12-19 18:55:18 +000073; VTABLE-NEXT: .globl _ZTV1D
74; VTABLE-LABEL: _ZTV1D:
75; VTABLE-NEXT: .int32 0
76; VTABLE-NEXT: .int32 _ZTI1D
77; VTABLE-NEXT: .int32 _ZN1AD2Ev
78; VTABLE-NEXT: .int32 _ZN1DD0Ev
79; VTABLE-NEXT: .int32 _ZN1D3fooEv
80; VTABLE-NEXT: .size _ZTV1D, 20
81@_ZTV1D = constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1D to i8*), i8* bitcast (%struct.A* (%struct.A*)* @_ZN1AD2Ev to i8*), i8* bitcast (void (%struct.D*)* @_ZN1DD0Ev to i8*), i8* bitcast (void (%struct.D*)* @_ZN1D3fooEv to i8*)], align 4
82
83; TYPEINFO: .type _ZTI1A,@object
84; TYPEINFO: .globl _ZTI1A
85; TYPEINFO-LABEL: _ZTI1A:
86; TYPEINFO-NEXT: .int32 _ZTVN10__cxxabiv117__class_type_infoE+8
87; TYPEINFO-NEXT: .int32 _ZTS1A
88; TYPEINFO-NEXT: .size _ZTI1A, 8
89@_ZTI1A = constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv117__class_type_infoE, i32 2) to i8*), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1A, i32 0, i32 0) }
90; TYPEINFO: .type _ZTI1B,@object
91; TYPEINFO: .globl _ZTI1B
92; TYPEINFO-LABEL: _ZTI1B:
93; TYPEINFO-NEXT: .int32 _ZTVN10__cxxabiv120__si_class_type_infoE+8
94; TYPEINFO-NEXT: .int32 _ZTS1B
95; TYPEINFO-NEXT: .int32 _ZTI1A
96; TYPEINFO-NEXT: .size _ZTI1B, 12
97@_ZTI1B = constant { i8*, i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv120__si_class_type_infoE, i32 2) to i8*), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1B, i32 0, i32 0), i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*) }
98; TYPEINFO: .type _ZTI1C,@object
99; TYPEINFO: .globl _ZTI1C
100; TYPEINFO-LABEL: _ZTI1C:
101; TYPEINFO-NEXT: .int32 _ZTVN10__cxxabiv120__si_class_type_infoE+8
102; TYPEINFO-NEXT: .int32 _ZTS1C
103; TYPEINFO-NEXT: .int32 _ZTI1A
104; TYPEINFO-NEXT: .size _ZTI1C, 12
105@_ZTI1C = constant { i8*, i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv120__si_class_type_infoE, i32 2) to i8*), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1C, i32 0, i32 0), i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*) }
106; TYPEINFO: .type _ZTI1D,@object
107; TYPEINFO: .globl _ZTI1D
108; TYPEINFO-LABEL: _ZTI1D:
109; TYPEINFO-NEXT: .int32 _ZTVN10__cxxabiv120__si_class_type_infoE+8
110; TYPEINFO-NEXT: .int32 _ZTS1D
111; TYPEINFO-NEXT: .int32 _ZTI1B
112; TYPEINFO-NEXT: .size _ZTI1D, 12
113@_ZTI1D = constant { i8*, i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv120__si_class_type_infoE, i32 2) to i8*), i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1D, i32 0, i32 0), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1B to i8*) }
114
115@g = global i32 0, align 4
116
117define void @_ZN1A3fooEv(%struct.A* %this) {
118entry:
119 store i32 2, i32* @g, align 4
120 ret void
121}
122
123define void @_ZN1B3fooEv(%struct.B* %this) {
124entry:
125 store i32 4, i32* @g, align 4
126 ret void
127}
128
129define void @_ZN1C3fooEv(%struct.C* %this) {
130entry:
131 store i32 6, i32* @g, align 4
132 ret void
133}
134
135define void @_ZN1D3fooEv(%struct.D* %this) {
136entry:
137 store i32 8, i32* @g, align 4
138 ret void
139}
140
141define linkonce_odr void @_ZN1AD0Ev(%struct.A* %this) {
142entry:
143 %0 = bitcast %struct.A* %this to i8*
144 tail call void @_ZdlPv(i8* %0)
145 ret void
146}
147
148define linkonce_odr void @_ZN1BD0Ev(%struct.B* %this) {
149entry:
150 %0 = bitcast %struct.B* %this to i8*
151 tail call void @_ZdlPv(i8* %0)
152 ret void
153}
154
155define linkonce_odr void @_ZN1CD0Ev(%struct.C* %this) {
156entry:
157 %0 = bitcast %struct.C* %this to i8*
158 tail call void @_ZdlPv(i8* %0)
159 ret void
160}
161
162define linkonce_odr %struct.A* @_ZN1AD2Ev(%struct.A* returned %this) {
163entry:
164 ret %struct.A* %this
165}
166
167define linkonce_odr void @_ZN1DD0Ev(%struct.D* %this) {
168entry:
169 %0 = bitcast %struct.D* %this to i8*
170 tail call void @_ZdlPv(i8* %0)
171 ret void
172}
173
174declare void @_ZdlPv(i8*)