Use "isa" since the variable isn't used.
[llvm-complete.git] / test / Analysis / TypeBasedAliasAnalysis / tbaa-path.ll
bloba2e4dc6ddcf039b23f9506f36cfebd8372a40eaf
1 ; RUN: opt < %s -tbaa -basicaa -aa-eval -evaluate-aa-metadata -print-no-aliases -print-may-aliases -disable-output 2>&1 | FileCheck %s
2 ; RUN: opt < %s -tbaa -basicaa -gvn -S | FileCheck %s --check-prefix=OPT
3 ; Generated from clang/test/CodeGen/tbaa.cpp with "-O1 -struct-path-tbaa -disable-llvm-optzns".
5 %struct.StructA = type { i16, i32, i16, i32 }
6 %struct.StructB = type { i16, %struct.StructA, i32 }
7 %struct.StructS = type { i16, i32 }
8 %struct.StructS2 = type { i16, i32 }
9 %struct.StructC = type { i16, %struct.StructB, i32 }
10 %struct.StructD = type { i16, %struct.StructB, i32, i8 }
12 define i32 @_Z1gPjP7StructAy(i32* %s, %struct.StructA* %A, i64 %count) #0 {
13 entry:
14 ; Access to i32* and &(A->f32).
15 ; CHECK: Function
16 ; CHECK: MayAlias:   store i32 4, i32* %f32, align 4, !tbaa !8 <->   store i32 1, i32* %0, align 4, !tbaa !6
17 ; OPT: define
18 ; OPT: store i32 1
19 ; OPT: store i32 4
20 ; OPT: %[[RET:.*]] = load i32, i32*
21 ; OPT: ret i32 %[[RET]]
22   %s.addr = alloca i32*, align 8
23   %A.addr = alloca %struct.StructA*, align 8
24   %count.addr = alloca i64, align 8
25   store i32* %s, i32** %s.addr, align 8, !tbaa !0
26   store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
27   store i64 %count, i64* %count.addr, align 8, !tbaa !4
28   %0 = load i32*, i32** %s.addr, align 8, !tbaa !0
29   store i32 1, i32* %0, align 4, !tbaa !6
30   %1 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
31   %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %1, i32 0, i32 1
32   store i32 4, i32* %f32, align 4, !tbaa !8
33   %2 = load i32*, i32** %s.addr, align 8, !tbaa !0
34   %3 = load i32, i32* %2, align 4, !tbaa !6
35   ret i32 %3
38 define i32 @_Z2g2PjP7StructAy(i32* %s, %struct.StructA* %A, i64 %count) #0 {
39 entry:
40 ; Access to i32* and &(A->f16).
41 ; CHECK: Function
42 ; CHECK: NoAlias:   store i16 4, i16* %f16, align 2, !tbaa !8 <->   store i32 1, i32* %0, align 4, !tbaa !6
43 ; OPT: define
44 ; OPT: store i32 1
45 ; OPT: store i16 4
46 ; Remove a load and propagate the value from store.
47 ; OPT: ret i32 1
48   %s.addr = alloca i32*, align 8
49   %A.addr = alloca %struct.StructA*, align 8
50   %count.addr = alloca i64, align 8
51   store i32* %s, i32** %s.addr, align 8, !tbaa !0
52   store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
53   store i64 %count, i64* %count.addr, align 8, !tbaa !4
54   %0 = load i32*, i32** %s.addr, align 8, !tbaa !0
55   store i32 1, i32* %0, align 4, !tbaa !6
56   %1 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
57   %f16 = getelementptr inbounds %struct.StructA, %struct.StructA* %1, i32 0, i32 0
58   store i16 4, i16* %f16, align 2, !tbaa !11
59   %2 = load i32*, i32** %s.addr, align 8, !tbaa !0
60   %3 = load i32, i32* %2, align 4, !tbaa !6
61   ret i32 %3
64 define i32 @_Z2g3P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 {
65 entry:
66 ; Access to &(A->f32) and &(B->a.f32).
67 ; CHECK: Function
68 ; CHECK: MayAlias:   store i32 4, i32* %f321, align 4, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
69 ; OPT: define
70 ; OPT: store i32 1
71 ; OPT: store i32 4
72 ; OPT: %[[RET:.*]] = load i32, i32*
73 ; OPT: ret i32 %[[RET]]
74   %A.addr = alloca %struct.StructA*, align 8
75   %B.addr = alloca %struct.StructB*, align 8
76   %count.addr = alloca i64, align 8
77   store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
78   store %struct.StructB* %B, %struct.StructB** %B.addr, align 8, !tbaa !0
79   store i64 %count, i64* %count.addr, align 8, !tbaa !4
80   %0 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
81   %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %0, i32 0, i32 1
82   store i32 1, i32* %f32, align 4, !tbaa !8
83   %1 = load %struct.StructB*, %struct.StructB** %B.addr, align 8, !tbaa !0
84   %a = getelementptr inbounds %struct.StructB, %struct.StructB* %1, i32 0, i32 1
85   %f321 = getelementptr inbounds %struct.StructA, %struct.StructA* %a, i32 0, i32 1
86   store i32 4, i32* %f321, align 4, !tbaa !12
87   %2 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
88   %f322 = getelementptr inbounds %struct.StructA, %struct.StructA* %2, i32 0, i32 1
89   %3 = load i32, i32* %f322, align 4, !tbaa !8
90   ret i32 %3
93 define i32 @_Z2g4P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 {
94 entry:
95 ; Access to &(A->f32) and &(B->a.f16).
96 ; CHECK: Function
97 ; CHECK: NoAlias:   store i16 4, i16* %f16, align 2, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
98 ; OPT: define
99 ; OPT: store i32 1
100 ; OPT: store i16 4
101 ; Remove a load and propagate the value from store.
102 ; OPT: ret i32 1
103   %A.addr = alloca %struct.StructA*, align 8
104   %B.addr = alloca %struct.StructB*, align 8
105   %count.addr = alloca i64, align 8
106   store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
107   store %struct.StructB* %B, %struct.StructB** %B.addr, align 8, !tbaa !0
108   store i64 %count, i64* %count.addr, align 8, !tbaa !4
109   %0 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
110   %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %0, i32 0, i32 1
111   store i32 1, i32* %f32, align 4, !tbaa !8
112   %1 = load %struct.StructB*, %struct.StructB** %B.addr, align 8, !tbaa !0
113   %a = getelementptr inbounds %struct.StructB, %struct.StructB* %1, i32 0, i32 1
114   %f16 = getelementptr inbounds %struct.StructA, %struct.StructA* %a, i32 0, i32 0
115   store i16 4, i16* %f16, align 2, !tbaa !14
116   %2 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
117   %f321 = getelementptr inbounds %struct.StructA, %struct.StructA* %2, i32 0, i32 1
118   %3 = load i32, i32* %f321, align 4, !tbaa !8
119   ret i32 %3
122 define i32 @_Z2g5P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 {
123 entry:
124 ; Access to &(A->f32) and &(B->f32).
125 ; CHECK: Function
126 ; CHECK: NoAlias:   store i32 4, i32* %f321, align 4, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
127 ; OPT: define
128 ; OPT: store i32 1
129 ; OPT: store i32 4
130 ; Remove a load and propagate the value from store.
131 ; OPT: ret i32 1
132   %A.addr = alloca %struct.StructA*, align 8
133   %B.addr = alloca %struct.StructB*, align 8
134   %count.addr = alloca i64, align 8
135   store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
136   store %struct.StructB* %B, %struct.StructB** %B.addr, align 8, !tbaa !0
137   store i64 %count, i64* %count.addr, align 8, !tbaa !4
138   %0 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
139   %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %0, i32 0, i32 1
140   store i32 1, i32* %f32, align 4, !tbaa !8
141   %1 = load %struct.StructB*, %struct.StructB** %B.addr, align 8, !tbaa !0
142   %f321 = getelementptr inbounds %struct.StructB, %struct.StructB* %1, i32 0, i32 2
143   store i32 4, i32* %f321, align 4, !tbaa !15
144   %2 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
145   %f322 = getelementptr inbounds %struct.StructA, %struct.StructA* %2, i32 0, i32 1
146   %3 = load i32, i32* %f322, align 4, !tbaa !8
147   ret i32 %3
150 define i32 @_Z2g6P7StructAP7StructBy(%struct.StructA* %A, %struct.StructB* %B, i64 %count) #0 {
151 entry:
152 ; Access to &(A->f32) and &(B->a.f32_2).
153 ; CHECK: Function
154 ; CHECK: NoAlias:   store i32 4, i32* %f32_2, align 4, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
155 ; OPT: define
156 ; OPT: store i32 1
157 ; OPT: store i32 4
158 ; Remove a load and propagate the value from store.
159 ; OPT: ret i32 1
160   %A.addr = alloca %struct.StructA*, align 8
161   %B.addr = alloca %struct.StructB*, align 8
162   %count.addr = alloca i64, align 8
163   store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
164   store %struct.StructB* %B, %struct.StructB** %B.addr, align 8, !tbaa !0
165   store i64 %count, i64* %count.addr, align 8, !tbaa !4
166   %0 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
167   %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %0, i32 0, i32 1
168   store i32 1, i32* %f32, align 4, !tbaa !8
169   %1 = load %struct.StructB*, %struct.StructB** %B.addr, align 8, !tbaa !0
170   %a = getelementptr inbounds %struct.StructB, %struct.StructB* %1, i32 0, i32 1
171   %f32_2 = getelementptr inbounds %struct.StructA, %struct.StructA* %a, i32 0, i32 3
172   store i32 4, i32* %f32_2, align 4, !tbaa !16
173   %2 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
174   %f321 = getelementptr inbounds %struct.StructA, %struct.StructA* %2, i32 0, i32 1
175   %3 = load i32, i32* %f321, align 4, !tbaa !8
176   ret i32 %3
179 define i32 @_Z2g7P7StructAP7StructSy(%struct.StructA* %A, %struct.StructS* %S, i64 %count) #0 {
180 entry:
181 ; Access to &(A->f32) and &(S->f32).
182 ; CHECK: Function
183 ; CHECK: NoAlias:   store i32 4, i32* %f321, align 4, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
184 ; OPT: define
185 ; OPT: store i32 1
186 ; OPT: store i32 4
187 ; Remove a load and propagate the value from store.
188 ; OPT: ret i32 1
189   %A.addr = alloca %struct.StructA*, align 8
190   %S.addr = alloca %struct.StructS*, align 8
191   %count.addr = alloca i64, align 8
192   store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
193   store %struct.StructS* %S, %struct.StructS** %S.addr, align 8, !tbaa !0
194   store i64 %count, i64* %count.addr, align 8, !tbaa !4
195   %0 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
196   %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %0, i32 0, i32 1
197   store i32 1, i32* %f32, align 4, !tbaa !8
198   %1 = load %struct.StructS*, %struct.StructS** %S.addr, align 8, !tbaa !0
199   %f321 = getelementptr inbounds %struct.StructS, %struct.StructS* %1, i32 0, i32 1
200   store i32 4, i32* %f321, align 4, !tbaa !17
201   %2 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
202   %f322 = getelementptr inbounds %struct.StructA, %struct.StructA* %2, i32 0, i32 1
203   %3 = load i32, i32* %f322, align 4, !tbaa !8
204   ret i32 %3
207 define i32 @_Z2g8P7StructAP7StructSy(%struct.StructA* %A, %struct.StructS* %S, i64 %count) #0 {
208 entry:
209 ; Access to &(A->f32) and &(S->f16).
210 ; CHECK: Function
211 ; CHECK: NoAlias:   store i16 4, i16* %f16, align 2, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
212 ; OPT: define
213 ; OPT: store i32 1
214 ; OPT: store i16 4
215 ; Remove a load and propagate the value from store.
216 ; OPT: ret i32 1
217   %A.addr = alloca %struct.StructA*, align 8
218   %S.addr = alloca %struct.StructS*, align 8
219   %count.addr = alloca i64, align 8
220   store %struct.StructA* %A, %struct.StructA** %A.addr, align 8, !tbaa !0
221   store %struct.StructS* %S, %struct.StructS** %S.addr, align 8, !tbaa !0
222   store i64 %count, i64* %count.addr, align 8, !tbaa !4
223   %0 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
224   %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %0, i32 0, i32 1
225   store i32 1, i32* %f32, align 4, !tbaa !8
226   %1 = load %struct.StructS*, %struct.StructS** %S.addr, align 8, !tbaa !0
227   %f16 = getelementptr inbounds %struct.StructS, %struct.StructS* %1, i32 0, i32 0
228   store i16 4, i16* %f16, align 2, !tbaa !19
229   %2 = load %struct.StructA*, %struct.StructA** %A.addr, align 8, !tbaa !0
230   %f321 = getelementptr inbounds %struct.StructA, %struct.StructA* %2, i32 0, i32 1
231   %3 = load i32, i32* %f321, align 4, !tbaa !8
232   ret i32 %3
235 define i32 @_Z2g9P7StructSP8StructS2y(%struct.StructS* %S, %struct.StructS2* %S2, i64 %count) #0 {
236 entry:
237 ; Access to &(S->f32) and &(S2->f32).
238 ; CHECK: Function
239 ; CHECK: NoAlias:   store i32 4, i32* %f321, align 4, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
240 ; OPT: define
241 ; OPT: store i32 1
242 ; OPT: store i32 4
243 ; Remove a load and propagate the value from store.
244 ; OPT: ret i32 1
245   %S.addr = alloca %struct.StructS*, align 8
246   %S2.addr = alloca %struct.StructS2*, align 8
247   %count.addr = alloca i64, align 8
248   store %struct.StructS* %S, %struct.StructS** %S.addr, align 8, !tbaa !0
249   store %struct.StructS2* %S2, %struct.StructS2** %S2.addr, align 8, !tbaa !0
250   store i64 %count, i64* %count.addr, align 8, !tbaa !4
251   %0 = load %struct.StructS*, %struct.StructS** %S.addr, align 8, !tbaa !0
252   %f32 = getelementptr inbounds %struct.StructS, %struct.StructS* %0, i32 0, i32 1
253   store i32 1, i32* %f32, align 4, !tbaa !17
254   %1 = load %struct.StructS2*, %struct.StructS2** %S2.addr, align 8, !tbaa !0
255   %f321 = getelementptr inbounds %struct.StructS2, %struct.StructS2* %1, i32 0, i32 1
256   store i32 4, i32* %f321, align 4, !tbaa !20
257   %2 = load %struct.StructS*, %struct.StructS** %S.addr, align 8, !tbaa !0
258   %f322 = getelementptr inbounds %struct.StructS, %struct.StructS* %2, i32 0, i32 1
259   %3 = load i32, i32* %f322, align 4, !tbaa !17
260   ret i32 %3
263 define i32 @_Z3g10P7StructSP8StructS2y(%struct.StructS* %S, %struct.StructS2* %S2, i64 %count) #0 {
264 entry:
265 ; Access to &(S->f32) and &(S2->f16).
266 ; CHECK: Function
267 ; CHECK: NoAlias:   store i16 4, i16* %f16, align 2, !tbaa !10 <->   store i32 1, i32* %f32, align 4, !tbaa !6
268 ; OPT: define
269 ; OPT: store i32 1
270 ; OPT: store i16 4
271 ; Remove a load and propagate the value from store.
272 ; OPT: ret i32 1
273   %S.addr = alloca %struct.StructS*, align 8
274   %S2.addr = alloca %struct.StructS2*, align 8
275   %count.addr = alloca i64, align 8
276   store %struct.StructS* %S, %struct.StructS** %S.addr, align 8, !tbaa !0
277   store %struct.StructS2* %S2, %struct.StructS2** %S2.addr, align 8, !tbaa !0
278   store i64 %count, i64* %count.addr, align 8, !tbaa !4
279   %0 = load %struct.StructS*, %struct.StructS** %S.addr, align 8, !tbaa !0
280   %f32 = getelementptr inbounds %struct.StructS, %struct.StructS* %0, i32 0, i32 1
281   store i32 1, i32* %f32, align 4, !tbaa !17
282   %1 = load %struct.StructS2*, %struct.StructS2** %S2.addr, align 8, !tbaa !0
283   %f16 = getelementptr inbounds %struct.StructS2, %struct.StructS2* %1, i32 0, i32 0
284   store i16 4, i16* %f16, align 2, !tbaa !22
285   %2 = load %struct.StructS*, %struct.StructS** %S.addr, align 8, !tbaa !0
286   %f321 = getelementptr inbounds %struct.StructS, %struct.StructS* %2, i32 0, i32 1
287   %3 = load i32, i32* %f321, align 4, !tbaa !17
288   ret i32 %3
291 define i32 @_Z3g11P7StructCP7StructDy(%struct.StructC* %C, %struct.StructD* %D, i64 %count) #0 {
292 entry:
293 ; Access to &(C->b.a.f32) and &(D->b.a.f32).
294 ; CHECK: Function
295 ; CHECK: NoAlias:   store i32 4, i32* %f323, align 4, !tbaa !12 <->   store i32 1, i32* %f32, align 4, !tbaa !6
296 ; OPT: define
297 ; OPT: store i32 1
298 ; OPT: store i32 4
299 ; Remove a load and propagate the value from store.
300 ; OPT: ret i32 1
301   %C.addr = alloca %struct.StructC*, align 8
302   %D.addr = alloca %struct.StructD*, align 8
303   %count.addr = alloca i64, align 8
304   store %struct.StructC* %C, %struct.StructC** %C.addr, align 8, !tbaa !0
305   store %struct.StructD* %D, %struct.StructD** %D.addr, align 8, !tbaa !0
306   store i64 %count, i64* %count.addr, align 8, !tbaa !4
307   %0 = load %struct.StructC*, %struct.StructC** %C.addr, align 8, !tbaa !0
308   %b = getelementptr inbounds %struct.StructC, %struct.StructC* %0, i32 0, i32 1
309   %a = getelementptr inbounds %struct.StructB, %struct.StructB* %b, i32 0, i32 1
310   %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %a, i32 0, i32 1
311   store i32 1, i32* %f32, align 4, !tbaa !23
312   %1 = load %struct.StructD*, %struct.StructD** %D.addr, align 8, !tbaa !0
313   %b1 = getelementptr inbounds %struct.StructD, %struct.StructD* %1, i32 0, i32 1
314   %a2 = getelementptr inbounds %struct.StructB, %struct.StructB* %b1, i32 0, i32 1
315   %f323 = getelementptr inbounds %struct.StructA, %struct.StructA* %a2, i32 0, i32 1
316   store i32 4, i32* %f323, align 4, !tbaa !25
317   %2 = load %struct.StructC*, %struct.StructC** %C.addr, align 8, !tbaa !0
318   %b4 = getelementptr inbounds %struct.StructC, %struct.StructC* %2, i32 0, i32 1
319   %a5 = getelementptr inbounds %struct.StructB, %struct.StructB* %b4, i32 0, i32 1
320   %f326 = getelementptr inbounds %struct.StructA, %struct.StructA* %a5, i32 0, i32 1
321   %3 = load i32, i32* %f326, align 4, !tbaa !23
322   ret i32 %3
325 define i32 @_Z3g12P7StructCP7StructDy(%struct.StructC* %C, %struct.StructD* %D, i64 %count) #0 {
326 entry:
327 ; Access to &(b1->a.f32) and &(b2->a.f32).
328 ; CHECK: Function
329 ; CHECK: MayAlias:   store i32 4, i32* %f325, align 4, !tbaa !6 <->   store i32 1, i32* %f32, align 4, !tbaa !6
330 ; OPT: define
331 ; OPT: store i32 1
332 ; OPT: store i32 4
333 ; OPT: %[[RET:.*]] = load i32, i32*
334 ; OPT: ret i32 %[[RET]]
335   %C.addr = alloca %struct.StructC*, align 8
336   %D.addr = alloca %struct.StructD*, align 8
337   %count.addr = alloca i64, align 8
338   %b1 = alloca %struct.StructB*, align 8
339   %b2 = alloca %struct.StructB*, align 8
340   store %struct.StructC* %C, %struct.StructC** %C.addr, align 8, !tbaa !0
341   store %struct.StructD* %D, %struct.StructD** %D.addr, align 8, !tbaa !0
342   store i64 %count, i64* %count.addr, align 8, !tbaa !4
343   %0 = load %struct.StructC*, %struct.StructC** %C.addr, align 8, !tbaa !0
344   %b = getelementptr inbounds %struct.StructC, %struct.StructC* %0, i32 0, i32 1
345   store %struct.StructB* %b, %struct.StructB** %b1, align 8, !tbaa !0
346   %1 = load %struct.StructD*, %struct.StructD** %D.addr, align 8, !tbaa !0
347   %b3 = getelementptr inbounds %struct.StructD, %struct.StructD* %1, i32 0, i32 1
348   store %struct.StructB* %b3, %struct.StructB** %b2, align 8, !tbaa !0
349   %2 = load %struct.StructB*, %struct.StructB** %b1, align 8, !tbaa !0
350   %a = getelementptr inbounds %struct.StructB, %struct.StructB* %2, i32 0, i32 1
351   %f32 = getelementptr inbounds %struct.StructA, %struct.StructA* %a, i32 0, i32 1
352   store i32 1, i32* %f32, align 4, !tbaa !12
353   %3 = load %struct.StructB*, %struct.StructB** %b2, align 8, !tbaa !0
354   %a4 = getelementptr inbounds %struct.StructB, %struct.StructB* %3, i32 0, i32 1
355   %f325 = getelementptr inbounds %struct.StructA, %struct.StructA* %a4, i32 0, i32 1
356   store i32 4, i32* %f325, align 4, !tbaa !12
357   %4 = load %struct.StructB*, %struct.StructB** %b1, align 8, !tbaa !0
358   %a6 = getelementptr inbounds %struct.StructB, %struct.StructB* %4, i32 0, i32 1
359   %f327 = getelementptr inbounds %struct.StructA, %struct.StructA* %a6, i32 0, i32 1
360   %5 = load i32, i32* %f327, align 4, !tbaa !12
361   ret i32 %5
364 attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
366 !0 = !{!1, !1, i64 0}
367 !1 = !{!"any pointer", !2}
368 !2 = !{!"omnipotent char", !3}
369 !3 = !{!"Simple C/C++ TBAA"}
370 !4 = !{!5, !5, i64 0}
371 !5 = !{!"long long", !2}
372 !6 = !{!7, !7, i64 0}
373 !7 = !{!"int", !2}
374 !8 = !{!9, !7, i64 4}
375 !9 = !{!"_ZTS7StructA", !10, i64 0, !7, i64 4, !10, i64 8, !7, i64 12}
376 !10 = !{!"short", !2}
377 !11 = !{!9, !10, i64 0}
378 !12 = !{!13, !7, i64 8}
379 !13 = !{!"_ZTS7StructB", !10, i64 0, !9, i64 4, !7, i64 20}
380 !14 = !{!13, !10, i64 4}
381 !15 = !{!13, !7, i64 20}
382 !16 = !{!13, !7, i64 16}
383 !17 = !{!18, !7, i64 4}
384 !18 = !{!"_ZTS7StructS", !10, i64 0, !7, i64 4}
385 !19 = !{!18, !10, i64 0}
386 !20 = !{!21, !7, i64 4}
387 !21 = !{!"_ZTS8StructS2", !10, i64 0, !7, i64 4}
388 !22 = !{!21, !10, i64 0}
389 !23 = !{!24, !7, i64 12}
390 !24 = !{!"_ZTS7StructC", !10, i64 0, !13, i64 4, !7, i64 28}
391 !25 = !{!26, !7, i64 12}
392 !26 = !{!"_ZTS7StructD", !10, i64 0, !13, i64 4, !7, i64 28, !2, i64 32}