select.ll 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. ; RUN: opt -S -jump-threading < %s | FileCheck %s
  2. declare void @foo()
  3. declare void @bar()
  4. declare void @baz()
  5. declare void @quux()
  6. ; Jump threading of branch with select as condition.
  7. ; Mostly theoretical since instruction combining simplifies all selects of
  8. ; booleans where at least one operand is true/false/undef.
  9. ; CHECK-LABEL: @test_br(
  10. ; CHECK-NEXT: entry:
  11. ; CHECK-NEXT: br i1 %cond, label %L1,
  12. define void @test_br(i1 %cond, i1 %value) nounwind {
  13. entry:
  14. br i1 %cond, label %L0, label %L3
  15. L0:
  16. %expr = select i1 %cond, i1 true, i1 %value
  17. br i1 %expr, label %L1, label %L2
  18. L1:
  19. call void @foo()
  20. ret void
  21. L2:
  22. call void @bar()
  23. ret void
  24. L3:
  25. call void @baz()
  26. br label %L0
  27. }
  28. ; Jump threading of switch with select as condition.
  29. ; CHECK-LABEL: @test_switch(
  30. ; CHECK-NEXT: entry:
  31. ; CHECK-NEXT: br i1 %cond, label %L1,
  32. define void @test_switch(i1 %cond, i8 %value) nounwind {
  33. entry:
  34. br i1 %cond, label %L0, label %L4
  35. L0:
  36. %expr = select i1 %cond, i8 1, i8 %value
  37. switch i8 %expr, label %L3 [i8 1, label %L1 i8 2, label %L2]
  38. L1:
  39. call void @foo()
  40. ret void
  41. L2:
  42. call void @bar()
  43. ret void
  44. L3:
  45. call void @baz()
  46. ret void
  47. L4:
  48. call void @quux()
  49. br label %L0
  50. }
  51. ; Make sure the blocks in the indirectbr test aren't trivially removable as
  52. ; successors by taking their addresses.
  53. @anchor = constant [3 x i8*] [
  54. i8* blockaddress(@test_indirectbr, %L1),
  55. i8* blockaddress(@test_indirectbr, %L2),
  56. i8* blockaddress(@test_indirectbr, %L3)
  57. ]
  58. ; Jump threading of indirectbr with select as address.
  59. ; CHECK-LABEL: @test_indirectbr(
  60. ; CHECK-NEXT: entry:
  61. ; CHECK-NEXT: br i1 %cond, label %L1, label %L3
  62. define void @test_indirectbr(i1 %cond, i8* %address) nounwind {
  63. entry:
  64. br i1 %cond, label %L0, label %L3
  65. L0:
  66. %indirect.goto.dest = select i1 %cond, i8* blockaddress(@test_indirectbr, %L1), i8* %address
  67. indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3]
  68. L1:
  69. call void @foo()
  70. ret void
  71. L2:
  72. call void @bar()
  73. ret void
  74. L3:
  75. call void @baz()
  76. ret void
  77. }
  78. ; A more complicated case: the condition is a select based on a comparison.
  79. ; CHECK-LABEL: @test_switch_cmp(
  80. ; CHECK-NEXT: entry:
  81. ; CHECK-NEXT: br i1 %cond, label %L0, label %[[THREADED:[A-Za-z.0-9]+]]
  82. ; CHECK: [[THREADED]]:
  83. ; CHECK-NEXT: call void @quux
  84. ; CHECK-NEXT: br label %L1
  85. define void @test_switch_cmp(i1 %cond, i32 %val, i8 %value) nounwind {
  86. entry:
  87. br i1 %cond, label %L0, label %L4
  88. L0:
  89. %val.phi = phi i32 [%val, %entry], [-1, %L4]
  90. %cmp = icmp slt i32 %val.phi, 0
  91. %expr = select i1 %cmp, i8 1, i8 %value
  92. switch i8 %expr, label %L3 [i8 1, label %L1 i8 2, label %L2]
  93. L1:
  94. call void @foo()
  95. ret void
  96. L2:
  97. call void @bar()
  98. ret void
  99. L3:
  100. call void @baz()
  101. ret void
  102. L4:
  103. call void @quux()
  104. br label %L0
  105. }
  106. ; Make sure the edge value of %0 from entry to L2 includes 0 and L3 is
  107. ; reachable.
  108. ; CHECK: test_switch_default
  109. ; CHECK: entry:
  110. ; CHECK: load
  111. ; CHECK: icmp
  112. ; CHECK: [[THREADED:[A-Za-z.0-9]+]]:
  113. ; CHECK: store
  114. ; CHECK: br
  115. ; CHECK: L2:
  116. ; CHECK: icmp
  117. define void @test_switch_default(i32* nocapture %status) nounwind {
  118. entry:
  119. %0 = load i32, i32* %status, align 4
  120. switch i32 %0, label %L2 [
  121. i32 5061, label %L1
  122. i32 0, label %L2
  123. ]
  124. L1:
  125. store i32 10025, i32* %status, align 4
  126. br label %L2
  127. L2:
  128. %1 = load i32, i32* %status, align 4
  129. %cmp57.i = icmp eq i32 %1, 0
  130. br i1 %cmp57.i, label %L3, label %L4
  131. L3:
  132. store i32 10000, i32* %status, align 4
  133. br label %L4
  134. L4:
  135. ret void
  136. }
  137. define void @unfold1(double %x, double %y) nounwind {
  138. entry:
  139. %sub = fsub double %x, %y
  140. %cmp = fcmp ogt double %sub, 1.000000e+01
  141. br i1 %cmp, label %cond.end4, label %cond.false
  142. cond.false: ; preds = %entry
  143. %add = fadd double %x, %y
  144. %cmp1 = fcmp ogt double %add, 1.000000e+01
  145. %add. = select i1 %cmp1, double %add, double 0.000000e+00
  146. br label %cond.end4
  147. cond.end4: ; preds = %entry, %cond.false
  148. %cond5 = phi double [ %add., %cond.false ], [ %sub, %entry ]
  149. %cmp6 = fcmp oeq double %cond5, 0.000000e+00
  150. br i1 %cmp6, label %if.then, label %if.end
  151. if.then: ; preds = %cond.end4
  152. call void @foo()
  153. br label %if.end
  154. if.end: ; preds = %if.then, %cond.end4
  155. ret void
  156. ; CHECK-LABEL: @unfold1
  157. ; CHECK: br i1 %cmp, label %cond.end4, label %cond.false
  158. ; CHECK: br i1 %cmp1, label %cond.end4, label %if.then
  159. ; CHECK: br i1 %cmp6, label %if.then, label %if.end
  160. ; CHECK: br label %if.end
  161. }
  162. define void @unfold2(i32 %x, i32 %y) nounwind {
  163. entry:
  164. %sub = sub nsw i32 %x, %y
  165. %cmp = icmp sgt i32 %sub, 10
  166. br i1 %cmp, label %cond.end4, label %cond.false
  167. cond.false: ; preds = %entry
  168. %add = add nsw i32 %x, %y
  169. %cmp1 = icmp sgt i32 %add, 10
  170. %add. = select i1 %cmp1, i32 0, i32 %add
  171. br label %cond.end4
  172. cond.end4: ; preds = %entry, %cond.false
  173. %cond5 = phi i32 [ %add., %cond.false ], [ %sub, %entry ]
  174. %cmp6 = icmp eq i32 %cond5, 0
  175. br i1 %cmp6, label %if.then, label %if.end
  176. if.then: ; preds = %cond.end4
  177. call void @foo()
  178. br label %if.end
  179. if.end: ; preds = %if.then, %cond.end4
  180. ret void
  181. ; CHECK-LABEL: @unfold2
  182. ; CHECK: br i1 %cmp, label %if.end, label %cond.false
  183. ; CHECK: br i1 %cmp1, label %if.then, label %cond.end4
  184. ; CHECK: br i1 %cmp6, label %if.then, label %if.end
  185. ; CHECK: br label %if.end
  186. }