switch-on-const-select.ll 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. ; RUN: opt < %s -simplifycfg -S | FileCheck %s
  2. ; Test basic folding to a conditional branch.
  3. define i32 @foo(i64 %x, i64 %y) nounwind {
  4. ; CHECK-LABEL: @foo(
  5. entry:
  6. %eq = icmp eq i64 %x, %y
  7. br i1 %eq, label %b, label %switch
  8. switch:
  9. %lt = icmp slt i64 %x, %y
  10. ; CHECK: br i1 %lt, label %a, label %b
  11. %qux = select i1 %lt, i32 0, i32 2
  12. switch i32 %qux, label %bees [
  13. i32 0, label %a
  14. i32 1, label %b
  15. i32 2, label %b
  16. ]
  17. a:
  18. tail call void @bees.a() nounwind
  19. ret i32 1
  20. ; CHECK: b:
  21. ; CHECK-NEXT: %retval = phi i32 [ 0, %switch ], [ 2, %entry ]
  22. b:
  23. %retval = phi i32 [0, %switch], [0, %switch], [2, %entry]
  24. tail call void @bees.b() nounwind
  25. ret i32 %retval
  26. ; CHECK-NOT: bees:
  27. bees:
  28. tail call void @llvm.trap() nounwind
  29. unreachable
  30. }
  31. ; Test basic folding to an unconditional branch.
  32. define i32 @bar(i64 %x, i64 %y) nounwind {
  33. ; CHECK-LABEL: @bar(
  34. entry:
  35. ; CHECK-NEXT: entry:
  36. ; CHECK-NEXT: tail call void @bees.a() [[NUW:#[0-9]+]]
  37. ; CHECK-NEXT: ret i32 0
  38. %lt = icmp slt i64 %x, %y
  39. %qux = select i1 %lt, i32 0, i32 2
  40. switch i32 %qux, label %bees [
  41. i32 0, label %a
  42. i32 1, label %b
  43. i32 2, label %a
  44. ]
  45. a:
  46. %retval = phi i32 [0, %entry], [0, %entry], [1, %b]
  47. tail call void @bees.a() nounwind
  48. ret i32 0
  49. b:
  50. tail call void @bees.b() nounwind
  51. br label %a
  52. bees:
  53. tail call void @llvm.trap() nounwind
  54. unreachable
  55. }
  56. ; Test the edge case where both values from the select are the default case.
  57. define void @bazz(i64 %x, i64 %y) nounwind {
  58. ; CHECK-LABEL: @bazz(
  59. entry:
  60. ; CHECK-NEXT: entry:
  61. ; CHECK-NEXT: tail call void @bees.b() [[NUW]]
  62. ; CHECK-NEXT: ret void
  63. %lt = icmp slt i64 %x, %y
  64. %qux = select i1 %lt, i32 10, i32 12
  65. switch i32 %qux, label %b [
  66. i32 0, label %a
  67. i32 1, label %bees
  68. i32 2, label %bees
  69. ]
  70. a:
  71. tail call void @bees.a() nounwind
  72. ret void
  73. b:
  74. tail call void @bees.b() nounwind
  75. ret void
  76. bees:
  77. tail call void @llvm.trap()
  78. unreachable
  79. }
  80. ; Test the edge case where both values from the select are equal.
  81. define void @quux(i64 %x, i64 %y) nounwind {
  82. ; CHECK-LABEL: @quux(
  83. entry:
  84. ; CHECK-NEXT: entry:
  85. ; CHECK-NEXT: tail call void @bees.a() [[NUW]]
  86. ; CHECK-NEXT: ret void
  87. %lt = icmp slt i64 %x, %y
  88. %qux = select i1 %lt, i32 0, i32 0
  89. switch i32 %qux, label %b [
  90. i32 0, label %a
  91. i32 1, label %bees
  92. i32 2, label %bees
  93. ]
  94. a:
  95. tail call void @bees.a() nounwind
  96. ret void
  97. b:
  98. tail call void @bees.b() nounwind
  99. ret void
  100. bees:
  101. tail call void @llvm.trap()
  102. unreachable
  103. }
  104. ; A final test, for phi node munging.
  105. define i32 @xyzzy(i64 %x, i64 %y) {
  106. ; CHECK-LABEL: @xyzzy(
  107. entry:
  108. %eq = icmp eq i64 %x, %y
  109. br i1 %eq, label %r, label %cont
  110. cont:
  111. ; CHECK: %lt = icmp slt i64 %x, %y
  112. %lt = icmp slt i64 %x, %y
  113. ; CHECK-NEXT: select i1 %lt, i32 -1, i32 1
  114. %qux = select i1 %lt, i32 0, i32 2
  115. switch i32 %qux, label %bees [
  116. i32 0, label %a
  117. i32 1, label %r
  118. i32 2, label %r
  119. ]
  120. r:
  121. %val = phi i32 [0, %entry], [1, %cont], [1, %cont]
  122. ret i32 %val
  123. a:
  124. ret i32 -1
  125. ; CHECK-NOT: bees:
  126. bees:
  127. tail call void @llvm.trap()
  128. unreachable
  129. }
  130. declare void @llvm.trap() nounwind noreturn
  131. declare void @bees.a() nounwind
  132. declare void @bees.b() nounwind
  133. ; CHECK: attributes [[NUW]] = { nounwind }
  134. ; CHECK: attributes #1 = { noreturn nounwind }