annotate docs/TypeMetadata.rst @ 120:1172e4bd9c6f

update 4.0.0
author mir3636
date Fri, 25 Nov 2016 19:14:25 +0900
parents
children 803732b1fca8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
1 =============
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
2 Type Metadata
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
3 =============
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
4
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
5 Type metadata is a mechanism that allows IR modules to co-operatively build
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
6 pointer sets corresponding to addresses within a given set of globals. LLVM's
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
7 `control flow integrity`_ implementation uses this metadata to efficiently
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
8 check (at each call site) that a given address corresponds to either a
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
9 valid vtable or function pointer for a given class or function type, and its
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
10 whole-program devirtualization pass uses the metadata to identify potential
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
11 callees for a given virtual call.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
12
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
13 To use the mechanism, a client creates metadata nodes with two elements:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
14
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
15 1. a byte offset into the global (generally zero for functions)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
16 2. a metadata object representing an identifier for the type
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
17
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
18 These metadata nodes are associated with globals by using global object
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
19 metadata attachments with the ``!type`` metadata kind.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
20
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
21 Each type identifier must exclusively identify either global variables
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
22 or functions.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
23
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
24 .. admonition:: Limitation
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
25
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
26 The current implementation only supports attaching metadata to functions on
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
27 the x86-32 and x86-64 architectures.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
28
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
29 An intrinsic, :ref:`llvm.type.test <type.test>`, is used to test whether a
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
30 given pointer is associated with a type identifier.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
31
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
32 .. _control flow integrity: http://clang.llvm.org/docs/ControlFlowIntegrity.html
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
33
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
34 Representing Type Information using Type Metadata
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
35 =================================================
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
36
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
37 This section describes how Clang represents C++ type information associated with
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
38 virtual tables using type metadata.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
39
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
40 Consider the following inheritance hierarchy:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
41
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
42 .. code-block:: c++
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
43
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
44 struct A {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
45 virtual void f();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
46 };
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
47
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
48 struct B : A {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
49 virtual void f();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
50 virtual void g();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
51 };
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
52
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
53 struct C {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
54 virtual void h();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
55 };
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
56
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
57 struct D : A, C {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
58 virtual void f();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
59 virtual void h();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
60 };
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
61
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
62 The virtual table objects for A, B, C and D look like this (under the Itanium ABI):
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
63
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
64 .. csv-table:: Virtual Table Layout for A, B, C, D
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
65 :header: Class, 0, 1, 2, 3, 4, 5, 6
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
66
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
67 A, A::offset-to-top, &A::rtti, &A::f
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
68 B, B::offset-to-top, &B::rtti, &B::f, &B::g
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
69 C, C::offset-to-top, &C::rtti, &C::h
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
70 D, D::offset-to-top, &D::rtti, &D::f, &D::h, D::offset-to-top, &D::rtti, thunk for &D::h
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
71
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
72 When an object of type A is constructed, the address of ``&A::f`` in A's
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
73 virtual table object is stored in the object's vtable pointer. In ABI parlance
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
74 this address is known as an `address point`_. Similarly, when an object of type
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
75 B is constructed, the address of ``&B::f`` is stored in the vtable pointer. In
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
76 this way, the vtable in B's virtual table object is compatible with A's vtable.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
77
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
78 D is a little more complicated, due to the use of multiple inheritance. Its
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
79 virtual table object contains two vtables, one compatible with A's vtable and
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
80 the other compatible with C's vtable. Objects of type D contain two virtual
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
81 pointers, one belonging to the A subobject and containing the address of
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
82 the vtable compatible with A's vtable, and the other belonging to the C
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
83 subobject and containing the address of the vtable compatible with C's vtable.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
84
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
85 The full set of compatibility information for the above class hierarchy is
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
86 shown below. The following table shows the name of a class, the offset of an
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
87 address point within that class's vtable and the name of one of the classes
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
88 with which that address point is compatible.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
89
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
90 .. csv-table:: Type Offsets for A, B, C, D
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
91 :header: VTable for, Offset, Compatible Class
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
92
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
93 A, 16, A
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
94 B, 16, A
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
95 , , B
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
96 C, 16, C
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
97 D, 16, A
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
98 , , D
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
99 , 48, C
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
100
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
101 The next step is to encode this compatibility information into the IR. The way
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
102 this is done is to create type metadata named after each of the compatible
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
103 classes, with which we associate each of the compatible address points in
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
104 each vtable. For example, these type metadata entries encode the compatibility
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
105 information for the above hierarchy:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
106
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
107 ::
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
108
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
109 @_ZTV1A = constant [...], !type !0
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
110 @_ZTV1B = constant [...], !type !0, !type !1
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
111 @_ZTV1C = constant [...], !type !2
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
112 @_ZTV1D = constant [...], !type !0, !type !3, !type !4
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
113
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
114 !0 = !{i64 16, !"_ZTS1A"}
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
115 !1 = !{i64 16, !"_ZTS1B"}
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
116 !2 = !{i64 16, !"_ZTS1C"}
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
117 !3 = !{i64 16, !"_ZTS1D"}
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
118 !4 = !{i64 48, !"_ZTS1C"}
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
119
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
120 With this type metadata, we can now use the ``llvm.type.test`` intrinsic to
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
121 test whether a given pointer is compatible with a type identifier. Working
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
122 backwards, if ``llvm.type.test`` returns true for a particular pointer,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
123 we can also statically determine the identities of the virtual functions
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
124 that a particular virtual call may call. For example, if a program assumes
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
125 a pointer to be a member of ``!"_ZST1A"``, we know that the address can
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
126 be only be one of ``_ZTV1A+16``, ``_ZTV1B+16`` or ``_ZTV1D+16`` (i.e. the
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
127 address points of the vtables of A, B and D respectively). If we then load
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
128 an address from that pointer, we know that the address can only be one of
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
129 ``&A::f``, ``&B::f`` or ``&D::f``.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
130
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
131 .. _address point: https://mentorembedded.github.io/cxx-abi/abi.html#vtable-general
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
132
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
133 Testing Addresses For Type Membership
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
134 =====================================
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
135
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
136 If a program tests an address using ``llvm.type.test``, this will cause
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
137 a link-time optimization pass, ``LowerTypeTests``, to replace calls to this
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
138 intrinsic with efficient code to perform type member tests. At a high level,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
139 the pass will lay out referenced globals in a consecutive memory region in
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
140 the object file, construct bit vectors that map onto that memory region,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
141 and generate code at each of the ``llvm.type.test`` call sites to test
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
142 pointers against those bit vectors. Because of the layout manipulation, the
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
143 globals' definitions must be available at LTO time. For more information,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
144 see the `control flow integrity design document`_.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
145
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
146 A type identifier that identifies functions is transformed into a jump table,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
147 which is a block of code consisting of one branch instruction for each
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
148 of the functions associated with the type identifier that branches to the
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
149 target function. The pass will redirect any taken function addresses to the
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
150 corresponding jump table entry. In the object file's symbol table, the jump
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
151 table entries take the identities of the original functions, so that addresses
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
152 taken outside the module will pass any verification done inside the module.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
153
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
154 Jump tables may call external functions, so their definitions need not
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
155 be available at LTO time. Note that if an externally defined function is
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
156 associated with a type identifier, there is no guarantee that its identity
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
157 within the module will be the same as its identity outside of the module,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
158 as the former will be the jump table entry if a jump table is necessary.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
159
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
160 The `GlobalLayoutBuilder`_ class is responsible for laying out the globals
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
161 efficiently to minimize the sizes of the underlying bitsets.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
162
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
163 .. _control flow integrity design document: http://clang.llvm.org/docs/ControlFlowIntegrityDesign.html
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
164
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
165 :Example:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
166
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
167 ::
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
168
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
169 target datalayout = "e-p:32:32"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
170
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
171 @a = internal global i32 0, !type !0
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
172 @b = internal global i32 0, !type !0, !type !1
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
173 @c = internal global i32 0, !type !1
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
174 @d = internal global [2 x i32] [i32 0, i32 0], !type !2
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
175
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
176 define void @e() !type !3 {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
177 ret void
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
178 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
179
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
180 define void @f() {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
181 ret void
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
182 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
183
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
184 declare void @g() !type !3
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
185
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
186 !0 = !{i32 0, !"typeid1"}
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
187 !1 = !{i32 0, !"typeid2"}
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
188 !2 = !{i32 4, !"typeid2"}
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
189 !3 = !{i32 0, !"typeid3"}
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
190
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
191 declare i1 @llvm.type.test(i8* %ptr, metadata %typeid) nounwind readnone
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
192
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
193 define i1 @foo(i32* %p) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
194 %pi8 = bitcast i32* %p to i8*
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
195 %x = call i1 @llvm.type.test(i8* %pi8, metadata !"typeid1")
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
196 ret i1 %x
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
197 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
198
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
199 define i1 @bar(i32* %p) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
200 %pi8 = bitcast i32* %p to i8*
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
201 %x = call i1 @llvm.type.test(i8* %pi8, metadata !"typeid2")
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
202 ret i1 %x
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
203 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
204
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
205 define i1 @baz(void ()* %p) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
206 %pi8 = bitcast void ()* %p to i8*
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
207 %x = call i1 @llvm.type.test(i8* %pi8, metadata !"typeid3")
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
208 ret i1 %x
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
209 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
210
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
211 define void @main() {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
212 %a1 = call i1 @foo(i32* @a) ; returns 1
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
213 %b1 = call i1 @foo(i32* @b) ; returns 1
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
214 %c1 = call i1 @foo(i32* @c) ; returns 0
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
215 %a2 = call i1 @bar(i32* @a) ; returns 0
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
216 %b2 = call i1 @bar(i32* @b) ; returns 1
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
217 %c2 = call i1 @bar(i32* @c) ; returns 1
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
218 %d02 = call i1 @bar(i32* getelementptr ([2 x i32]* @d, i32 0, i32 0)) ; returns 0
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
219 %d12 = call i1 @bar(i32* getelementptr ([2 x i32]* @d, i32 0, i32 1)) ; returns 1
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
220 %e = call i1 @baz(void ()* @e) ; returns 1
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
221 %f = call i1 @baz(void ()* @f) ; returns 0
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
222 %g = call i1 @baz(void ()* @g) ; returns 1
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
223 ret void
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
224 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
225
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
226 .. _GlobalLayoutBuilder: http://llvm.org/klaus/llvm/blob/master/include/llvm/Transforms/IPO/LowerTypeTests.h