indirectbr.ll 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. ; RUN: opt -S -simplifycfg < %s | FileCheck %s
  2. ; SimplifyCFG should eliminate redundant indirectbr edges.
  3. ; CHECK: indbrtest0
  4. ; CHECK: indirectbr i8* %t, [label %BB0, label %BB1, label %BB2]
  5. ; CHECK: %x = phi i32 [ 0, %BB0 ], [ 1, %entry ]
  6. declare void @foo()
  7. declare void @A()
  8. declare void @B(i32)
  9. declare void @C()
  10. define void @indbrtest0(i8** %P, i8** %Q) {
  11. entry:
  12. store i8* blockaddress(@indbrtest0, %BB0), i8** %P
  13. store i8* blockaddress(@indbrtest0, %BB1), i8** %P
  14. store i8* blockaddress(@indbrtest0, %BB2), i8** %P
  15. call void @foo()
  16. %t = load i8*, i8** %Q
  17. indirectbr i8* %t, [label %BB0, label %BB1, label %BB2, label %BB0, label %BB1, label %BB2]
  18. BB0:
  19. call void @A()
  20. br label %BB1
  21. BB1:
  22. %x = phi i32 [ 0, %BB0 ], [ 1, %entry ], [ 1, %entry ]
  23. call void @B(i32 %x)
  24. ret void
  25. BB2:
  26. call void @C()
  27. ret void
  28. }
  29. ; SimplifyCFG should convert the indirectbr into a directbr. It would be even
  30. ; better if it removed the branch altogether, but simplifycfdg currently misses
  31. ; that because the predecessor is the entry block.
  32. ; CHECK: indbrtest1
  33. ; CHECK: br label %BB0
  34. define void @indbrtest1(i8** %P, i8** %Q) {
  35. entry:
  36. store i8* blockaddress(@indbrtest1, %BB0), i8** %P
  37. call void @foo()
  38. %t = load i8*, i8** %Q
  39. indirectbr i8* %t, [label %BB0, label %BB0]
  40. BB0:
  41. call void @A()
  42. ret void
  43. }
  44. ; SimplifyCFG should notice that BB0 does not have its address taken and
  45. ; remove it from entry's successor list.
  46. ; CHECK: indbrtest2
  47. ; CHECK: entry:
  48. ; CHECK-NEXT: unreachable
  49. define void @indbrtest2(i8* %t) {
  50. entry:
  51. indirectbr i8* %t, [label %BB0, label %BB0]
  52. BB0:
  53. ret void
  54. }
  55. ; Make sure the blocks in the next few tests aren't trivially removable as
  56. ; successors by taking their addresses.
  57. @anchor = constant [13 x i8*] [
  58. i8* blockaddress(@indbrtest3, %L1), i8* blockaddress(@indbrtest3, %L2), i8* blockaddress(@indbrtest3, %L3),
  59. i8* blockaddress(@indbrtest4, %L1), i8* blockaddress(@indbrtest4, %L2), i8* blockaddress(@indbrtest4, %L3),
  60. i8* blockaddress(@indbrtest5, %L1), i8* blockaddress(@indbrtest5, %L2), i8* blockaddress(@indbrtest5, %L3), i8* blockaddress(@indbrtest5, %L4),
  61. i8* blockaddress(@indbrtest6, %L1), i8* blockaddress(@indbrtest6, %L2), i8* blockaddress(@indbrtest6, %L3)
  62. ]
  63. ; SimplifyCFG should turn the indirectbr into a conditional branch on the
  64. ; condition of the select.
  65. ; CHECK-LABEL: @indbrtest3(
  66. ; CHECK-NEXT: entry:
  67. ; CHECK-NEXT: br i1 %cond, label %L1, label %L2
  68. ; CHECK-NOT: indirectbr
  69. ; CHECK-NOT: br
  70. ; CHECK-NOT: L3:
  71. define void @indbrtest3(i1 %cond, i8* %address) nounwind {
  72. entry:
  73. %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest3, %L1), i8* blockaddress(@indbrtest3, %L2)
  74. indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3]
  75. L1:
  76. call void @A()
  77. ret void
  78. L2:
  79. call void @C()
  80. ret void
  81. L3:
  82. call void @foo()
  83. ret void
  84. }
  85. ; SimplifyCFG should turn the indirectbr into an unconditional branch to the
  86. ; only possible destination.
  87. ; As in @indbrtest1, it should really remove the branch entirely, but it doesn't
  88. ; because it's in the entry block.
  89. ; CHECK-LABEL: @indbrtest4(
  90. ; CHECK-NEXT: entry:
  91. ; CHECK-NEXT: br label %L1
  92. define void @indbrtest4(i1 %cond) nounwind {
  93. entry:
  94. %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest4, %L1), i8* blockaddress(@indbrtest4, %L1)
  95. indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3]
  96. L1:
  97. call void @A()
  98. ret void
  99. L2:
  100. call void @C()
  101. ret void
  102. L3:
  103. call void @foo()
  104. ret void
  105. }
  106. ; SimplifyCFG should turn the indirectbr into an unreachable because neither
  107. ; destination is listed as a successor.
  108. ; CHECK-LABEL: @indbrtest5(
  109. ; CHECK-NEXT: entry:
  110. ; CHECK-NEXT: unreachable
  111. ; CHECK-NEXT: }
  112. define void @indbrtest5(i1 %cond, i8* %anchor) nounwind {
  113. entry:
  114. %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest5, %L1), i8* blockaddress(@indbrtest5, %L2)
  115. ; This needs to have more than one successor for this test, otherwise it gets
  116. ; replaced with an unconditional branch to the single successor.
  117. indirectbr i8* %indirect.goto.dest, [label %L3, label %L4]
  118. L1:
  119. call void @A()
  120. ret void
  121. L2:
  122. call void @C()
  123. ret void
  124. L3:
  125. call void @foo()
  126. ret void
  127. L4:
  128. call void @foo()
  129. ; This keeps blockaddresses not otherwise listed as successors from being zapped
  130. ; before SimplifyCFG even looks at the indirectbr.
  131. indirectbr i8* %anchor, [label %L1, label %L2]
  132. }
  133. ; The same as above, except the selected addresses are equal.
  134. ; CHECK-LABEL: @indbrtest6(
  135. ; CHECK-NEXT: entry:
  136. ; CHECK-NEXT: unreachable
  137. ; CHECK-NEXT: }
  138. define void @indbrtest6(i1 %cond, i8* %anchor) nounwind {
  139. entry:
  140. %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest6, %L1), i8* blockaddress(@indbrtest6, %L1)
  141. ; This needs to have more than one successor for this test, otherwise it gets
  142. ; replaced with an unconditional branch to the single successor.
  143. indirectbr i8* %indirect.goto.dest, [label %L2, label %L3]
  144. L1:
  145. call void @A()
  146. ret void
  147. L2:
  148. call void @C()
  149. ret void
  150. L3:
  151. call void @foo()
  152. ; This keeps blockaddresses not otherwise listed as successors from being zapped
  153. ; before SimplifyCFG even looks at the indirectbr.
  154. indirectbr i8* %anchor, [label %L1, label %L2]
  155. }
  156. ; PR10072
  157. @xblkx.bbs = internal unnamed_addr constant [9 x i8*] [i8* blockaddress(@indbrtest7, %xblkx.begin), i8* blockaddress(@indbrtest7, %xblkx.begin3), i8* blockaddress(@indbrtest7, %xblkx.begin4), i8* blockaddress(@indbrtest7, %xblkx.begin5), i8* blockaddress(@indbrtest7, %xblkx.begin6), i8* blockaddress(@indbrtest7, %xblkx.begin7), i8* blockaddress(@indbrtest7, %xblkx.begin8), i8* blockaddress(@indbrtest7, %xblkx.begin9), i8* blockaddress(@indbrtest7, %xblkx.end)]
  158. define void @indbrtest7() {
  159. escape-string.top:
  160. %xval202x = call i32 @xfunc5x()
  161. br label %xlab5x
  162. xlab8x: ; preds = %xlab5x
  163. %xvaluex = call i32 @xselectorx()
  164. %xblkx.x = getelementptr [9 x i8*], [9 x i8*]* @xblkx.bbs, i32 0, i32 %xvaluex
  165. %xblkx.load = load i8*, i8** %xblkx.x
  166. indirectbr i8* %xblkx.load, [label %xblkx.begin, label %xblkx.begin3, label %xblkx.begin4, label %xblkx.begin5, label %xblkx.begin6, label %xblkx.begin7, label %xblkx.begin8, label %xblkx.begin9, label %xblkx.end]
  167. xblkx.begin:
  168. br label %xblkx.end
  169. xblkx.begin3:
  170. br label %xblkx.end
  171. xblkx.begin4:
  172. br label %xblkx.end
  173. xblkx.begin5:
  174. br label %xblkx.end
  175. xblkx.begin6:
  176. br label %xblkx.end
  177. xblkx.begin7:
  178. br label %xblkx.end
  179. xblkx.begin8:
  180. br label %xblkx.end
  181. xblkx.begin9:
  182. br label %xblkx.end
  183. xblkx.end:
  184. %yes.0 = phi i1 [ false, %xblkx.begin ], [ true, %xlab8x ], [ false, %xblkx.begin9 ], [ false, %xblkx.begin8 ], [ false, %xblkx.begin7 ], [ false, %xblkx.begin6 ], [ false, %xblkx.begin5 ], [ true, %xblkx.begin4 ], [ false, %xblkx.begin3 ]
  185. br i1 %yes.0, label %v2j, label %xlab17x
  186. v2j:
  187. ; CHECK: %xunusedx = call i32 @xactionx()
  188. %xunusedx = call i32 @xactionx()
  189. br label %xlab4x
  190. xlab17x:
  191. br label %xlab4x
  192. xlab4x:
  193. %incr19 = add i32 %xval704x.0, 1
  194. br label %xlab5x
  195. xlab5x:
  196. %xval704x.0 = phi i32 [ 0, %escape-string.top ], [ %incr19, %xlab4x ]
  197. %xval10x = icmp ult i32 %xval704x.0, %xval202x
  198. br i1 %xval10x, label %xlab8x, label %xlab9x
  199. xlab9x:
  200. ret void
  201. }
  202. declare i32 @xfunc5x()
  203. declare i8 @xfunc7x()
  204. declare i32 @xselectorx()
  205. declare i32 @xactionx()