preserve-branchweights.ll 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. ; RUN: opt -simplifycfg -S -o - < %s | FileCheck %s
  2. declare void @helper(i32)
  3. define void @test1(i1 %a, i1 %b) {
  4. ; CHECK-LABEL: @test1(
  5. entry:
  6. br i1 %a, label %Y, label %X, !prof !0
  7. ; CHECK: br i1 %or.cond, label %Z, label %Y, !prof !0
  8. X:
  9. %c = or i1 %b, false
  10. br i1 %c, label %Z, label %Y, !prof !1
  11. Y:
  12. call void @helper(i32 0)
  13. ret void
  14. Z:
  15. call void @helper(i32 1)
  16. ret void
  17. }
  18. define void @test2(i1 %a, i1 %b) {
  19. ; CHECK-LABEL: @test2(
  20. entry:
  21. br i1 %a, label %X, label %Y, !prof !1
  22. ; CHECK: br i1 %or.cond, label %Z, label %Y, !prof !1
  23. ; CHECK-NOT: !prof
  24. X:
  25. %c = or i1 %b, false
  26. br i1 %c, label %Z, label %Y, !prof !2
  27. Y:
  28. call void @helper(i32 0)
  29. ret void
  30. Z:
  31. call void @helper(i32 1)
  32. ret void
  33. }
  34. define void @test3(i1 %a, i1 %b) {
  35. ; CHECK-LABEL: @test3(
  36. ; CHECK-NOT: !prof
  37. entry:
  38. br i1 %a, label %X, label %Y, !prof !1
  39. X:
  40. %c = or i1 %b, false
  41. br i1 %c, label %Z, label %Y
  42. Y:
  43. call void @helper(i32 0)
  44. ret void
  45. Z:
  46. call void @helper(i32 1)
  47. ret void
  48. }
  49. define void @test4(i1 %a, i1 %b) {
  50. ; CHECK-LABEL: @test4(
  51. ; CHECK-NOT: !prof
  52. entry:
  53. br i1 %a, label %X, label %Y
  54. X:
  55. %c = or i1 %b, false
  56. br i1 %c, label %Z, label %Y, !prof !1
  57. Y:
  58. call void @helper(i32 0)
  59. ret void
  60. Z:
  61. call void @helper(i32 1)
  62. ret void
  63. }
  64. ;; test5 - The case where it jumps to the default target will be removed.
  65. define void @test5(i32 %M, i32 %N) nounwind uwtable {
  66. entry:
  67. switch i32 %N, label %sw2 [
  68. i32 1, label %sw2
  69. i32 2, label %sw.bb
  70. i32 3, label %sw.bb1
  71. ], !prof !3
  72. ; CHECK-LABEL: @test5(
  73. ; CHECK: switch i32 %N, label %sw2 [
  74. ; CHECK: i32 3, label %sw.bb1
  75. ; CHECK: i32 2, label %sw.bb
  76. ; CHECK: ], !prof !2
  77. sw.bb:
  78. call void @helper(i32 0)
  79. br label %sw.epilog
  80. sw.bb1:
  81. call void @helper(i32 1)
  82. br label %sw.epilog
  83. sw2:
  84. call void @helper(i32 2)
  85. br label %sw.epilog
  86. sw.epilog:
  87. ret void
  88. }
  89. ;; test6 - Some cases of the second switch are pruned during optimization.
  90. ;; Then the second switch will be converted to a branch, finally, the first
  91. ;; switch and the branch will be merged into a single switch.
  92. define void @test6(i32 %M, i32 %N) nounwind uwtable {
  93. entry:
  94. switch i32 %N, label %sw2 [
  95. i32 1, label %sw2
  96. i32 2, label %sw.bb
  97. i32 3, label %sw.bb1
  98. ], !prof !4
  99. ; CHECK-LABEL: @test6(
  100. ; CHECK: switch i32 %N, label %sw.epilog
  101. ; CHECK: i32 3, label %sw.bb1
  102. ; CHECK: i32 2, label %sw.bb
  103. ; CHECK: i32 4, label %sw.bb5
  104. ; CHECK: ], !prof !3
  105. sw.bb:
  106. call void @helper(i32 0)
  107. br label %sw.epilog
  108. sw.bb1:
  109. call void @helper(i32 1)
  110. br label %sw.epilog
  111. sw2:
  112. ;; Here "case 2" is invalidated since the default case of the first switch
  113. ;; does not include "case 2".
  114. switch i32 %N, label %sw.epilog [
  115. i32 2, label %sw.bb4
  116. i32 4, label %sw.bb5
  117. ], !prof !5
  118. sw.bb4:
  119. call void @helper(i32 2)
  120. br label %sw.epilog
  121. sw.bb5:
  122. call void @helper(i32 3)
  123. br label %sw.epilog
  124. sw.epilog:
  125. ret void
  126. }
  127. ;; This test is based on test1 but swapped the targets of the second branch.
  128. define void @test1_swap(i1 %a, i1 %b) {
  129. ; CHECK-LABEL: @test1_swap(
  130. entry:
  131. br i1 %a, label %Y, label %X, !prof !0
  132. ; CHECK: br i1 %or.cond, label %Y, label %Z, !prof !4
  133. X:
  134. %c = or i1 %b, false
  135. br i1 %c, label %Y, label %Z, !prof !1
  136. Y:
  137. call void @helper(i32 0)
  138. ret void
  139. Z:
  140. call void @helper(i32 1)
  141. ret void
  142. }
  143. define void @test7(i1 %a, i1 %b) {
  144. ; CHECK-LABEL: @test7(
  145. entry:
  146. %c = or i1 %b, false
  147. br i1 %a, label %Y, label %X, !prof !0
  148. ; CHECK: br i1 %brmerge, label %Y, label %Z, !prof !5
  149. X:
  150. br i1 %c, label %Y, label %Z, !prof !6
  151. Y:
  152. call void @helper(i32 0)
  153. ret void
  154. Z:
  155. call void @helper(i32 1)
  156. ret void
  157. }
  158. ; Test basic folding to a conditional branch.
  159. define void @test8(i64 %x, i64 %y) nounwind {
  160. ; CHECK-LABEL: @test8(
  161. entry:
  162. %lt = icmp slt i64 %x, %y
  163. ; CHECK: br i1 %lt, label %a, label %b, !prof !6
  164. %qux = select i1 %lt, i32 0, i32 2
  165. switch i32 %qux, label %bees [
  166. i32 0, label %a
  167. i32 1, label %b
  168. i32 2, label %b
  169. ], !prof !7
  170. a:
  171. call void @helper(i32 0) nounwind
  172. ret void
  173. b:
  174. call void @helper(i32 1) nounwind
  175. ret void
  176. bees:
  177. call void @helper(i32 2) nounwind
  178. ret void
  179. }
  180. ; Test edge splitting when the default target has icmp and unconditinal
  181. ; branch
  182. define i1 @test9(i32 %x, i32 %y) nounwind {
  183. ; CHECK-LABEL: @test9(
  184. entry:
  185. switch i32 %x, label %bees [
  186. i32 0, label %a
  187. i32 1, label %end
  188. i32 2, label %end
  189. ], !prof !7
  190. ; CHECK: switch i32 %x, label %bees [
  191. ; CHECK: i32 0, label %a
  192. ; CHECK: i32 1, label %end
  193. ; CHECK: i32 2, label %end
  194. ; CHECK: i32 92, label %end
  195. ; CHECK: ], !prof !7
  196. a:
  197. call void @helper(i32 0) nounwind
  198. %reta = icmp slt i32 %x, %y
  199. ret i1 %reta
  200. bees:
  201. %tmp = icmp eq i32 %x, 92
  202. br label %end
  203. end:
  204. ; CHECK: end:
  205. ; CHECK: %ret = phi i1 [ true, %entry ], [ false, %bees ], [ true, %entry ], [ true, %entry ]
  206. %ret = phi i1 [ true, %entry ], [%tmp, %bees], [true, %entry]
  207. call void @helper(i32 2) nounwind
  208. ret i1 %ret
  209. }
  210. define void @test10(i32 %x) nounwind readnone ssp noredzone {
  211. entry:
  212. switch i32 %x, label %lor.rhs [
  213. i32 2, label %lor.end
  214. i32 1, label %lor.end
  215. i32 3, label %lor.end
  216. ], !prof !7
  217. lor.rhs:
  218. call void @helper(i32 1) nounwind
  219. ret void
  220. lor.end:
  221. call void @helper(i32 0) nounwind
  222. ret void
  223. ; CHECK-LABEL: @test10(
  224. ; CHECK: %x.off = add i32 %x, -1
  225. ; CHECK: %switch = icmp ult i32 %x.off, 3
  226. ; CHECK: br i1 %switch, label %lor.end, label %lor.rhs, !prof !8
  227. }
  228. ; Remove dead cases from the switch.
  229. define void @test11(i32 %x) nounwind {
  230. %i = shl i32 %x, 1
  231. switch i32 %i, label %a [
  232. i32 21, label %b
  233. i32 24, label %c
  234. ], !prof !8
  235. ; CHECK-LABEL: @test11(
  236. ; CHECK: %cond = icmp eq i32 %i, 24
  237. ; CHECK: br i1 %cond, label %c, label %a, !prof !9
  238. a:
  239. call void @helper(i32 0) nounwind
  240. ret void
  241. b:
  242. call void @helper(i32 1) nounwind
  243. ret void
  244. c:
  245. call void @helper(i32 2) nounwind
  246. ret void
  247. }
  248. ;; test12 - Don't crash if the whole switch is removed
  249. define void @test12(i32 %M, i32 %N) nounwind uwtable {
  250. entry:
  251. switch i32 %N, label %sw.bb [
  252. i32 1, label %sw.bb
  253. ], !prof !9
  254. ; CHECK-LABEL: @test12(
  255. ; CHECK-NEXT: entry:
  256. ; CHECK-NEXT: call void @helper
  257. ; CHECK-NEXT: ret void
  258. sw.bb:
  259. call void @helper(i32 0)
  260. br label %sw.epilog
  261. sw.epilog:
  262. ret void
  263. }
  264. ;; If every case is dead, make sure they are all removed. This used to
  265. ;; crash trying to merge the metadata.
  266. define void @test13(i32 %x) nounwind {
  267. entry:
  268. %i = shl i32 %x, 1
  269. switch i32 %i, label %a [
  270. i32 21, label %b
  271. i32 25, label %c
  272. ], !prof !8
  273. ; CHECK-LABEL: @test13(
  274. ; CHECK-NEXT: entry:
  275. ; CHECK-NEXT: call void @helper
  276. ; CHECK-NEXT: ret void
  277. a:
  278. call void @helper(i32 0) nounwind
  279. ret void
  280. b:
  281. call void @helper(i32 1) nounwind
  282. ret void
  283. c:
  284. call void @helper(i32 2) nounwind
  285. ret void
  286. }
  287. ;; When folding branches to common destination, the updated branch weights
  288. ;; can exceed uint32 by more than factor of 2. We should keep halving the
  289. ;; weights until they can fit into uint32.
  290. @max_regno = common global i32 0, align 4
  291. define void @test14(i32* %old, i32 %final) {
  292. ; CHECK-LABEL: @test14
  293. ; CHECK: br i1 %or.cond, label %for.exit, label %for.inc, !prof !10
  294. for.cond:
  295. br label %for.cond2
  296. for.cond2:
  297. %i.1 = phi i32 [ %inc19, %for.inc ], [ 0, %for.cond ]
  298. %bit.0 = phi i32 [ %shl, %for.inc ], [ 1, %for.cond ]
  299. %tobool = icmp eq i32 %bit.0, 0
  300. br i1 %tobool, label %for.exit, label %for.body3, !prof !10
  301. for.body3:
  302. %v3 = load i32, i32* @max_regno, align 4
  303. %cmp4 = icmp eq i32 %i.1, %v3
  304. br i1 %cmp4, label %for.exit, label %for.inc, !prof !11
  305. for.inc:
  306. %shl = shl i32 %bit.0, 1
  307. %inc19 = add nsw i32 %i.1, 1
  308. br label %for.cond2
  309. for.exit:
  310. ret void
  311. }
  312. !0 = !{!"branch_weights", i32 3, i32 5}
  313. !1 = !{!"branch_weights", i32 1, i32 1}
  314. !2 = !{!"branch_weights", i32 1, i32 2}
  315. !3 = !{!"branch_weights", i32 4, i32 3, i32 2, i32 1}
  316. !4 = !{!"branch_weights", i32 4, i32 3, i32 2, i32 1}
  317. !5 = !{!"branch_weights", i32 7, i32 6, i32 5}
  318. !6 = !{!"branch_weights", i32 1, i32 3}
  319. !7 = !{!"branch_weights", i32 33, i32 9, i32 8, i32 7}
  320. !8 = !{!"branch_weights", i32 33, i32 9, i32 8}
  321. !9 = !{!"branch_weights", i32 7, i32 6}
  322. !10 = !{!"branch_weights", i32 672646, i32 21604207}
  323. !11 = !{!"branch_weights", i32 6960, i32 21597248}
  324. ; CHECK: !0 = !{!"branch_weights", i32 5, i32 11}
  325. ; CHECK: !1 = !{!"branch_weights", i32 1, i32 5}
  326. ; CHECK: !2 = !{!"branch_weights", i32 7, i32 1, i32 2}
  327. ; CHECK: !3 = !{!"branch_weights", i32 49, i32 12, i32 24, i32 35}
  328. ; CHECK: !4 = !{!"branch_weights", i32 11, i32 5}
  329. ; CHECK: !5 = !{!"branch_weights", i32 17, i32 15}
  330. ; CHECK: !6 = !{!"branch_weights", i32 9, i32 7}
  331. ; CHECK: !7 = !{!"branch_weights", i32 17, i32 9, i32 8, i32 7, i32 17}
  332. ; CHECK: !8 = !{!"branch_weights", i32 24, i32 33}
  333. ; CHECK: !9 = !{!"branch_weights", i32 8, i32 33}
  334. ;; The false weight prints out as a negative integer here, but inside llvm, we
  335. ;; treat the weight as an unsigned integer.
  336. ; CHECK: !10 = !{!"branch_weights", i32 112017436, i32 -735157296}