with-parent-loops.ll 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce < %s 2>&1 | FileCheck %s
  2. ; This test checks if we update the LoopInfo correctly in the presence
  3. ; of parents, uncles and cousins.
  4. ; Function Attrs: alwaysinline
  5. define void @inner_loop(i32* %arr, i32* %a_len_ptr, i32 %n) #0 {
  6. ; CHECK: irce: in function inner_loop: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
  7. entry:
  8. %len = load i32, i32* %a_len_ptr, !range !0
  9. %first.itr.check = icmp sgt i32 %n, 0
  10. br i1 %first.itr.check, label %loop, label %exit
  11. loop: ; preds = %in.bounds, %entry
  12. %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
  13. %idx.next = add i32 %idx, 1
  14. %abc = icmp slt i32 %idx, %len
  15. br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1
  16. in.bounds: ; preds = %loop
  17. %addr = getelementptr i32, i32* %arr, i32 %idx
  18. store i32 0, i32* %addr
  19. %next = icmp slt i32 %idx.next, %n
  20. br i1 %next, label %loop, label %exit
  21. out.of.bounds: ; preds = %loop
  22. ret void
  23. exit: ; preds = %in.bounds, %entry
  24. ret void
  25. }
  26. ; Function Attrs: alwaysinline
  27. define void @with_parent(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count) #0 {
  28. ; CHECK: irce: in function with_parent: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting>
  29. entry:
  30. br label %loop
  31. loop: ; preds = %inner_loop.exit, %entry
  32. %idx = phi i32 [ 0, %entry ], [ %idx.next, %inner_loop.exit ]
  33. %idx.next = add i32 %idx, 1
  34. %next = icmp ult i32 %idx.next, %parent.count
  35. %len.i = load i32, i32* %a_len_ptr, !range !0
  36. %first.itr.check.i = icmp sgt i32 %n, 0
  37. br i1 %first.itr.check.i, label %loop.i, label %exit.i
  38. loop.i: ; preds = %in.bounds.i, %loop
  39. %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ]
  40. %idx.next.i = add i32 %idx.i, 1
  41. %abc.i = icmp slt i32 %idx.i, %len.i
  42. br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1
  43. in.bounds.i: ; preds = %loop.i
  44. %addr.i = getelementptr i32, i32* %arr, i32 %idx.i
  45. store i32 0, i32* %addr.i
  46. %next.i = icmp slt i32 %idx.next.i, %n
  47. br i1 %next.i, label %loop.i, label %exit.i
  48. out.of.bounds.i: ; preds = %loop.i
  49. br label %inner_loop.exit
  50. exit.i: ; preds = %in.bounds.i, %loop
  51. br label %inner_loop.exit
  52. inner_loop.exit: ; preds = %exit.i, %out.of.bounds.i
  53. br i1 %next, label %loop, label %exit
  54. exit: ; preds = %inner_loop.exit
  55. ret void
  56. }
  57. ; Function Attrs: alwaysinline
  58. define void @with_grandparent(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 {
  59. ; CHECK: irce: in function with_grandparent: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting>
  60. entry:
  61. br label %loop
  62. loop: ; preds = %with_parent.exit, %entry
  63. %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit ]
  64. %idx.next = add i32 %idx, 1
  65. %next = icmp ult i32 %idx.next, %grandparent.count
  66. br label %loop.i
  67. loop.i: ; preds = %inner_loop.exit.i, %loop
  68. %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %inner_loop.exit.i ]
  69. %idx.next.i = add i32 %idx.i, 1
  70. %next.i = icmp ult i32 %idx.next.i, %parent.count
  71. %len.i.i = load i32, i32* %a_len_ptr, !range !0
  72. %first.itr.check.i.i = icmp sgt i32 %n, 0
  73. br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i
  74. loop.i.i: ; preds = %in.bounds.i.i, %loop.i
  75. %idx.i.i = phi i32 [ 0, %loop.i ], [ %idx.next.i.i, %in.bounds.i.i ]
  76. %idx.next.i.i = add i32 %idx.i.i, 1
  77. %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i
  78. br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1
  79. in.bounds.i.i: ; preds = %loop.i.i
  80. %addr.i.i = getelementptr i32, i32* %arr, i32 %idx.i.i
  81. store i32 0, i32* %addr.i.i
  82. %next.i.i = icmp slt i32 %idx.next.i.i, %n
  83. br i1 %next.i.i, label %loop.i.i, label %exit.i.i
  84. out.of.bounds.i.i: ; preds = %loop.i.i
  85. br label %inner_loop.exit.i
  86. exit.i.i: ; preds = %in.bounds.i.i, %loop.i
  87. br label %inner_loop.exit.i
  88. inner_loop.exit.i: ; preds = %exit.i.i, %out.of.bounds.i.i
  89. br i1 %next.i, label %loop.i, label %with_parent.exit
  90. with_parent.exit: ; preds = %inner_loop.exit.i
  91. br i1 %next, label %loop, label %exit
  92. exit: ; preds = %with_parent.exit
  93. ret void
  94. }
  95. ; Function Attrs: alwaysinline
  96. define void @with_sibling(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count) #0 {
  97. ; CHECK: irce: in function with_sibling: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting>
  98. ; CHECK: irce: in function with_sibling: constrained Loop at depth 2 containing: %loop.i6<header><exiting>,%in.bounds.i9<latch><exiting>
  99. entry:
  100. br label %loop
  101. loop: ; preds = %inner_loop.exit12, %entry
  102. %idx = phi i32 [ 0, %entry ], [ %idx.next, %inner_loop.exit12 ]
  103. %idx.next = add i32 %idx, 1
  104. %next = icmp ult i32 %idx.next, %parent.count
  105. %len.i = load i32, i32* %a_len_ptr, !range !0
  106. %first.itr.check.i = icmp sgt i32 %n, 0
  107. br i1 %first.itr.check.i, label %loop.i, label %exit.i
  108. loop.i: ; preds = %in.bounds.i, %loop
  109. %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ]
  110. %idx.next.i = add i32 %idx.i, 1
  111. %abc.i = icmp slt i32 %idx.i, %len.i
  112. br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1
  113. in.bounds.i: ; preds = %loop.i
  114. %addr.i = getelementptr i32, i32* %arr, i32 %idx.i
  115. store i32 0, i32* %addr.i
  116. %next.i = icmp slt i32 %idx.next.i, %n
  117. br i1 %next.i, label %loop.i, label %exit.i
  118. out.of.bounds.i: ; preds = %loop.i
  119. br label %inner_loop.exit
  120. exit.i: ; preds = %in.bounds.i, %loop
  121. br label %inner_loop.exit
  122. inner_loop.exit: ; preds = %exit.i, %out.of.bounds.i
  123. %len.i1 = load i32, i32* %a_len_ptr, !range !0
  124. %first.itr.check.i2 = icmp sgt i32 %n, 0
  125. br i1 %first.itr.check.i2, label %loop.i6, label %exit.i11
  126. loop.i6: ; preds = %in.bounds.i9, %inner_loop.exit
  127. %idx.i3 = phi i32 [ 0, %inner_loop.exit ], [ %idx.next.i4, %in.bounds.i9 ]
  128. %idx.next.i4 = add i32 %idx.i3, 1
  129. %abc.i5 = icmp slt i32 %idx.i3, %len.i1
  130. br i1 %abc.i5, label %in.bounds.i9, label %out.of.bounds.i10, !prof !1
  131. in.bounds.i9: ; preds = %loop.i6
  132. %addr.i7 = getelementptr i32, i32* %arr, i32 %idx.i3
  133. store i32 0, i32* %addr.i7
  134. %next.i8 = icmp slt i32 %idx.next.i4, %n
  135. br i1 %next.i8, label %loop.i6, label %exit.i11
  136. out.of.bounds.i10: ; preds = %loop.i6
  137. br label %inner_loop.exit12
  138. exit.i11: ; preds = %in.bounds.i9, %inner_loop.exit
  139. br label %inner_loop.exit12
  140. inner_loop.exit12: ; preds = %exit.i11, %out.of.bounds.i10
  141. br i1 %next, label %loop, label %exit
  142. exit: ; preds = %inner_loop.exit12
  143. ret void
  144. }
  145. ; Function Attrs: alwaysinline
  146. define void @with_cousin(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 {
  147. ; CHECK: irce: in function with_cousin: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting>
  148. ; CHECK: irce: in function with_cousin: constrained Loop at depth 3 containing: %loop.i.i10<header><exiting>,%in.bounds.i.i13<latch><exiting>
  149. entry:
  150. br label %loop
  151. loop: ; preds = %with_parent.exit17, %entry
  152. %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit17 ]
  153. %idx.next = add i32 %idx, 1
  154. %next = icmp ult i32 %idx.next, %grandparent.count
  155. br label %loop.i
  156. loop.i: ; preds = %inner_loop.exit.i, %loop
  157. %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %inner_loop.exit.i ]
  158. %idx.next.i = add i32 %idx.i, 1
  159. %next.i = icmp ult i32 %idx.next.i, %parent.count
  160. %len.i.i = load i32, i32* %a_len_ptr, !range !0
  161. %first.itr.check.i.i = icmp sgt i32 %n, 0
  162. br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i
  163. loop.i.i: ; preds = %in.bounds.i.i, %loop.i
  164. %idx.i.i = phi i32 [ 0, %loop.i ], [ %idx.next.i.i, %in.bounds.i.i ]
  165. %idx.next.i.i = add i32 %idx.i.i, 1
  166. %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i
  167. br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1
  168. in.bounds.i.i: ; preds = %loop.i.i
  169. %addr.i.i = getelementptr i32, i32* %arr, i32 %idx.i.i
  170. store i32 0, i32* %addr.i.i
  171. %next.i.i = icmp slt i32 %idx.next.i.i, %n
  172. br i1 %next.i.i, label %loop.i.i, label %exit.i.i
  173. out.of.bounds.i.i: ; preds = %loop.i.i
  174. br label %inner_loop.exit.i
  175. exit.i.i: ; preds = %in.bounds.i.i, %loop.i
  176. br label %inner_loop.exit.i
  177. inner_loop.exit.i: ; preds = %exit.i.i, %out.of.bounds.i.i
  178. br i1 %next.i, label %loop.i, label %with_parent.exit
  179. with_parent.exit: ; preds = %inner_loop.exit.i
  180. br label %loop.i6
  181. loop.i6: ; preds = %inner_loop.exit.i16, %with_parent.exit
  182. %idx.i1 = phi i32 [ 0, %with_parent.exit ], [ %idx.next.i2, %inner_loop.exit.i16 ]
  183. %idx.next.i2 = add i32 %idx.i1, 1
  184. %next.i3 = icmp ult i32 %idx.next.i2, %parent.count
  185. %len.i.i4 = load i32, i32* %a_len_ptr, !range !0
  186. %first.itr.check.i.i5 = icmp sgt i32 %n, 0
  187. br i1 %first.itr.check.i.i5, label %loop.i.i10, label %exit.i.i15
  188. loop.i.i10: ; preds = %in.bounds.i.i13, %loop.i6
  189. %idx.i.i7 = phi i32 [ 0, %loop.i6 ], [ %idx.next.i.i8, %in.bounds.i.i13 ]
  190. %idx.next.i.i8 = add i32 %idx.i.i7, 1
  191. %abc.i.i9 = icmp slt i32 %idx.i.i7, %len.i.i4
  192. br i1 %abc.i.i9, label %in.bounds.i.i13, label %out.of.bounds.i.i14, !prof !1
  193. in.bounds.i.i13: ; preds = %loop.i.i10
  194. %addr.i.i11 = getelementptr i32, i32* %arr, i32 %idx.i.i7
  195. store i32 0, i32* %addr.i.i11
  196. %next.i.i12 = icmp slt i32 %idx.next.i.i8, %n
  197. br i1 %next.i.i12, label %loop.i.i10, label %exit.i.i15
  198. out.of.bounds.i.i14: ; preds = %loop.i.i10
  199. br label %inner_loop.exit.i16
  200. exit.i.i15: ; preds = %in.bounds.i.i13, %loop.i6
  201. br label %inner_loop.exit.i16
  202. inner_loop.exit.i16: ; preds = %exit.i.i15, %out.of.bounds.i.i14
  203. br i1 %next.i3, label %loop.i6, label %with_parent.exit17
  204. with_parent.exit17: ; preds = %inner_loop.exit.i16
  205. br i1 %next, label %loop, label %exit
  206. exit: ; preds = %with_parent.exit17
  207. ret void
  208. }
  209. ; Function Attrs: alwaysinline
  210. define void @with_uncle(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 {
  211. ; CHECK: irce: in function with_uncle: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting>
  212. ; CHECK: irce: in function with_uncle: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting>
  213. entry:
  214. br label %loop
  215. loop: ; preds = %with_parent.exit, %entry
  216. %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit ]
  217. %idx.next = add i32 %idx, 1
  218. %next = icmp ult i32 %idx.next, %grandparent.count
  219. %len.i = load i32, i32* %a_len_ptr, !range !0
  220. %first.itr.check.i = icmp sgt i32 %n, 0
  221. br i1 %first.itr.check.i, label %loop.i, label %exit.i
  222. loop.i: ; preds = %in.bounds.i, %loop
  223. %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ]
  224. %idx.next.i = add i32 %idx.i, 1
  225. %abc.i = icmp slt i32 %idx.i, %len.i
  226. br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1
  227. in.bounds.i: ; preds = %loop.i
  228. %addr.i = getelementptr i32, i32* %arr, i32 %idx.i
  229. store i32 0, i32* %addr.i
  230. %next.i = icmp slt i32 %idx.next.i, %n
  231. br i1 %next.i, label %loop.i, label %exit.i
  232. out.of.bounds.i: ; preds = %loop.i
  233. br label %inner_loop.exit
  234. exit.i: ; preds = %in.bounds.i, %loop
  235. br label %inner_loop.exit
  236. inner_loop.exit: ; preds = %exit.i, %out.of.bounds.i
  237. br label %loop.i4
  238. loop.i4: ; preds = %inner_loop.exit.i, %inner_loop.exit
  239. %idx.i1 = phi i32 [ 0, %inner_loop.exit ], [ %idx.next.i2, %inner_loop.exit.i ]
  240. %idx.next.i2 = add i32 %idx.i1, 1
  241. %next.i3 = icmp ult i32 %idx.next.i2, %parent.count
  242. %len.i.i = load i32, i32* %a_len_ptr, !range !0
  243. %first.itr.check.i.i = icmp sgt i32 %n, 0
  244. br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i
  245. loop.i.i: ; preds = %in.bounds.i.i, %loop.i4
  246. %idx.i.i = phi i32 [ 0, %loop.i4 ], [ %idx.next.i.i, %in.bounds.i.i ]
  247. %idx.next.i.i = add i32 %idx.i.i, 1
  248. %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i
  249. br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1
  250. in.bounds.i.i: ; preds = %loop.i.i
  251. %addr.i.i = getelementptr i32, i32* %arr, i32 %idx.i.i
  252. store i32 0, i32* %addr.i.i
  253. %next.i.i = icmp slt i32 %idx.next.i.i, %n
  254. br i1 %next.i.i, label %loop.i.i, label %exit.i.i
  255. out.of.bounds.i.i: ; preds = %loop.i.i
  256. br label %inner_loop.exit.i
  257. exit.i.i: ; preds = %in.bounds.i.i, %loop.i4
  258. br label %inner_loop.exit.i
  259. inner_loop.exit.i: ; preds = %exit.i.i, %out.of.bounds.i.i
  260. br i1 %next.i3, label %loop.i4, label %with_parent.exit
  261. with_parent.exit: ; preds = %inner_loop.exit.i
  262. br i1 %next, label %loop, label %exit
  263. exit: ; preds = %with_parent.exit
  264. ret void
  265. }
  266. attributes #0 = { alwaysinline }
  267. !0 = !{i32 0, i32 2147483647}
  268. !1 = !{!"branch_weights", i32 64, i32 4}