tbaa-path.ll 18 KB

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