[WebAssembly] Add -m:e to the target triple.
[oota-llvm.git] / test / CodeGen / WebAssembly / vtable.ll
1 ; RUN: llc < %s -asm-verbose=false | FileCheck %s --check-prefix=TYPEINFONAME
2 ; RUN: llc < %s -asm-verbose=false | FileCheck %s --check-prefix=VTABLE
3 ; RUN: llc < %s -asm-verbose=false | FileCheck %s --check-prefix=TYPEINFO
4
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
14 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
15 target triple = "wasm32-unknown-unknown"
16
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
39 ; VTABLE-NEXT:  .section .data.rel.ro,"aw",@progbits
40 ; 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
50 ; VTABLE-NEXT:  .globl _ZTV1B
51 ; VTABLE-LABEL: _ZTV1B:
52 ; VTABLE-NEXT:  .int32 0
53 ; VTABLE-NEXT:  .int32 _ZTI1B
54 ; VTABLE-NEXT:  .int32 _ZN1AD2Ev
55 ; VTABLE-NEXT:  .int32 _ZN1BD0Ev
56 ; VTABLE-NEXT:  .int32 _ZN1B3fooEv
57 ; VTABLE-NEXT:  .size _ZTV1B, 20
58 @_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
59 ; VTABLE:       .type _ZTV1C,@object
60 ; VTABLE-NEXT:  .globl _ZTV1C
61 ; VTABLE-LABEL: _ZTV1C:
62 ; VTABLE-NEXT:  .int32 0
63 ; VTABLE-NEXT:  .int32 _ZTI1C
64 ; VTABLE-NEXT:  .int32 _ZN1AD2Ev
65 ; VTABLE-NEXT:  .int32 _ZN1CD0Ev
66 ; VTABLE-NEXT:  .int32 _ZN1C3fooEv
67 ; VTABLE-NEXT:  .size _ZTV1C, 20
68 @_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
69 ; VTABLE:       .type _ZTV1D,@object
70 ; VTABLE-NEXT:  .globl _ZTV1D
71 ; VTABLE-LABEL: _ZTV1D:
72 ; VTABLE-NEXT:  .int32 0
73 ; VTABLE-NEXT:  .int32 _ZTI1D
74 ; VTABLE-NEXT:  .int32 _ZN1AD2Ev
75 ; VTABLE-NEXT:  .int32 _ZN1DD0Ev
76 ; VTABLE-NEXT:  .int32 _ZN1D3fooEv
77 ; VTABLE-NEXT:  .size _ZTV1D, 20
78 @_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
79
80 ; TYPEINFO:       .type _ZTI1A,@object
81 ; TYPEINFO:       .globl _ZTI1A
82 ; TYPEINFO-LABEL: _ZTI1A:
83 ; TYPEINFO-NEXT:  .int32 _ZTVN10__cxxabiv117__class_type_infoE+8
84 ; TYPEINFO-NEXT:  .int32 _ZTS1A
85 ; TYPEINFO-NEXT:  .size _ZTI1A, 8
86 @_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) }
87 ; TYPEINFO:       .type _ZTI1B,@object
88 ; TYPEINFO:       .globl _ZTI1B
89 ; TYPEINFO-LABEL: _ZTI1B:
90 ; TYPEINFO-NEXT:  .int32 _ZTVN10__cxxabiv120__si_class_type_infoE+8
91 ; TYPEINFO-NEXT:  .int32 _ZTS1B
92 ; TYPEINFO-NEXT:  .int32 _ZTI1A
93 ; TYPEINFO-NEXT:  .size _ZTI1B, 12
94 @_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*) }
95 ; TYPEINFO:       .type _ZTI1C,@object
96 ; TYPEINFO:       .globl _ZTI1C
97 ; TYPEINFO-LABEL: _ZTI1C:
98 ; TYPEINFO-NEXT:  .int32 _ZTVN10__cxxabiv120__si_class_type_infoE+8
99 ; TYPEINFO-NEXT:  .int32 _ZTS1C
100 ; TYPEINFO-NEXT:  .int32 _ZTI1A
101 ; TYPEINFO-NEXT:  .size _ZTI1C, 12
102 @_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*) }
103 ; TYPEINFO:       .type _ZTI1D,@object
104 ; TYPEINFO:       .globl _ZTI1D
105 ; TYPEINFO-LABEL: _ZTI1D:
106 ; TYPEINFO-NEXT:  .int32 _ZTVN10__cxxabiv120__si_class_type_infoE+8
107 ; TYPEINFO-NEXT:  .int32 _ZTS1D
108 ; TYPEINFO-NEXT:  .int32 _ZTI1B
109 ; TYPEINFO-NEXT:  .size _ZTI1D, 12
110 @_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*) }
111
112 @g = global i32 0, align 4
113
114 define void @_ZN1A3fooEv(%struct.A* %this) {
115 entry:
116   store i32 2, i32* @g, align 4
117   ret void
118 }
119
120 define void @_ZN1B3fooEv(%struct.B* %this) {
121 entry:
122   store i32 4, i32* @g, align 4
123   ret void
124 }
125
126 define void @_ZN1C3fooEv(%struct.C* %this) {
127 entry:
128   store i32 6, i32* @g, align 4
129   ret void
130 }
131
132 define void @_ZN1D3fooEv(%struct.D* %this) {
133 entry:
134   store i32 8, i32* @g, align 4
135   ret void
136 }
137
138 define linkonce_odr void @_ZN1AD0Ev(%struct.A* %this) {
139 entry:
140   %0 = bitcast %struct.A* %this to i8*
141   tail call void @_ZdlPv(i8* %0)
142   ret void
143 }
144
145 define linkonce_odr void @_ZN1BD0Ev(%struct.B* %this) {
146 entry:
147   %0 = bitcast %struct.B* %this to i8*
148   tail call void @_ZdlPv(i8* %0)
149   ret void
150 }
151
152 define linkonce_odr void @_ZN1CD0Ev(%struct.C* %this) {
153 entry:
154   %0 = bitcast %struct.C* %this to i8*
155   tail call void @_ZdlPv(i8* %0)
156   ret void
157 }
158
159 define linkonce_odr %struct.A* @_ZN1AD2Ev(%struct.A* returned %this) {
160 entry:
161   ret %struct.A* %this
162 }
163
164 define linkonce_odr void @_ZN1DD0Ev(%struct.D* %this) {
165 entry:
166   %0 = bitcast %struct.D* %this to i8*
167   tail call void @_ZdlPv(i8* %0)
168   ret void
169 }
170
171 declare void @_ZdlPv(i8*)