nary-add.ll 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. ; RUN: opt < %s -nary-reassociate -S | FileCheck %s
  2. target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
  3. declare void @foo(i32)
  4. ; foo(a + c);
  5. ; foo((a + (b + c));
  6. ; =>
  7. ; t = a + c;
  8. ; foo(t);
  9. ; foo(t + b);
  10. define void @left_reassociate(i32 %a, i32 %b, i32 %c) {
  11. ; CHECK-LABEL: @left_reassociate(
  12. %1 = add i32 %a, %c
  13. ; CHECK: [[BASE:%[a-zA-Z0-9]+]] = add i32 %a, %c
  14. call void @foo(i32 %1)
  15. %2 = add i32 %b, %c
  16. %3 = add i32 %a, %2
  17. ; CHECK: add i32 [[BASE]], %b
  18. call void @foo(i32 %3)
  19. ret void
  20. }
  21. ; foo(a + c);
  22. ; foo((a + b) + c);
  23. ; =>
  24. ; t = a + c;
  25. ; foo(t);
  26. ; foo(t + b);
  27. define void @right_reassociate(i32 %a, i32 %b, i32 %c) {
  28. ; CHECK-LABEL: @right_reassociate(
  29. %1 = add i32 %a, %c
  30. ; CHECK: [[BASE:%[a-zA-Z0-9]+]] = add i32 %a, %c
  31. call void @foo(i32 %1)
  32. %2 = add i32 %a, %b
  33. %3 = add i32 %2, %c
  34. ; CHECK: add i32 [[BASE]], %b
  35. call void @foo(i32 %3)
  36. ret void
  37. }
  38. ; t1 = a + c;
  39. ; foo(t1);
  40. ; t2 = a + b;
  41. ; foo(t2);
  42. ; t3 = t2 + c;
  43. ; foo(t3);
  44. ;
  45. ; Do not rewrite t3 into t1 + b because t2 is used elsewhere and is likely free.
  46. define void @no_reassociate(i32 %a, i32 %b, i32 %c) {
  47. ; CHECK-LABEL: @no_reassociate(
  48. %1 = add i32 %a, %c
  49. ; CHECK: add i32 %a, %c
  50. call void @foo(i32 %1)
  51. %2 = add i32 %a, %b
  52. ; CHECK: add i32 %a, %b
  53. call void @foo(i32 %2)
  54. %3 = add i32 %2, %c
  55. ; CHECK: add i32 %2, %c
  56. call void @foo(i32 %3)
  57. ret void
  58. }
  59. ; if (p1)
  60. ; foo(a + c);
  61. ; if (p2)
  62. ; foo(a + c);
  63. ; if (p3)
  64. ; foo((a + b) + c);
  65. ;
  66. ; No action because (a + c) does not dominate ((a + b) + c).
  67. define void @conditional(i1 %p1, i1 %p2, i1 %p3, i32 %a, i32 %b, i32 %c) {
  68. ; CHECK-LABEL: @conditional(
  69. entry:
  70. br i1 %p1, label %then1, label %branch1
  71. then1:
  72. %0 = add i32 %a, %c
  73. ; CHECK: add i32 %a, %c
  74. call void @foo(i32 %0)
  75. br label %branch1
  76. branch1:
  77. br i1 %p2, label %then2, label %branch2
  78. then2:
  79. %1 = add i32 %a, %c
  80. ; CHECK: add i32 %a, %c
  81. call void @foo(i32 %1)
  82. br label %branch2
  83. branch2:
  84. br i1 %p3, label %then3, label %return
  85. then3:
  86. %2 = add i32 %a, %b
  87. ; CHECK: %2 = add i32 %a, %b
  88. %3 = add i32 %2, %c
  89. ; CHECK: add i32 %2, %c
  90. call void @foo(i32 %3)
  91. br label %return
  92. return:
  93. ret void
  94. }
  95. ; This test involves more conditional reassociation candidates. It exercises
  96. ; the stack optimization in tryReassociatedAdd that pops the candidates that
  97. ; do not dominate the current instruction.
  98. ;
  99. ; def1
  100. ; cond1
  101. ; / \
  102. ; / \
  103. ; cond2 use2
  104. ; / \
  105. ; / \
  106. ; def2 def3
  107. ; cond3
  108. ; / \
  109. ; / \
  110. ; def4 use1
  111. ;
  112. ; NaryReassociate should match use1 with def3, and use2 with def1.
  113. define void @conditional2(i32 %a, i32 %b, i32 %c, i1 %cond1, i1 %cond2, i1 %cond3) {
  114. entry:
  115. %def1 = add i32 %a, %b
  116. br i1 %cond1, label %bb1, label %bb6
  117. bb1:
  118. br i1 %cond2, label %bb2, label %bb3
  119. bb2:
  120. %def2 = add i32 %a, %b
  121. call void @foo(i32 %def2)
  122. ret void
  123. bb3:
  124. %def3 = add i32 %a, %b
  125. br i1 %cond3, label %bb4, label %bb5
  126. bb4:
  127. %def4 = add i32 %a, %b
  128. call void @foo(i32 %def4)
  129. ret void
  130. bb5:
  131. %0 = add i32 %a, %c
  132. %1 = add i32 %0, %b
  133. ; CHECK: [[t1:%[0-9]+]] = add i32 %def3, %c
  134. call void @foo(i32 %1) ; foo((a + c) + b);
  135. ; CHECK-NEXT: call void @foo(i32 [[t1]])
  136. ret void
  137. bb6:
  138. %2 = add i32 %a, %c
  139. %3 = add i32 %2, %b
  140. ; CHECK: [[t2:%[0-9]+]] = add i32 %def1, %c
  141. call void @foo(i32 %3) ; foo((a + c) + b);
  142. ; CHECK-NEXT: call void @foo(i32 [[t2]])
  143. ret void
  144. }
  145. ; foo((a + b) + c)
  146. ; foo(((a + d) + b) + c)
  147. ; =>
  148. ; t = (a + b) + c;
  149. ; foo(t);
  150. ; foo(t + d);
  151. define void @quaternary(i32 %a, i32 %b, i32 %c, i32 %d) {
  152. ; CHECK-LABEL: @quaternary(
  153. %1 = add i32 %a, %b
  154. %2 = add i32 %1, %c
  155. call void @foo(i32 %2)
  156. ; CHECK: call void @foo(i32 [[TMP1:%[a-zA-Z0-9]]])
  157. %3 = add i32 %a, %d
  158. %4 = add i32 %3, %b
  159. %5 = add i32 %4, %c
  160. ; CHECK: [[TMP2:%[a-zA-Z0-9]]] = add i32 [[TMP1]], %d
  161. call void @foo(i32 %5)
  162. ; CHECK: call void @foo(i32 [[TMP2]]
  163. ret void
  164. }
  165. define void @iterative(i32 %a, i32 %b, i32 %c) {
  166. %ab = add i32 %a, %b
  167. %abc = add i32 %ab, %c
  168. call void @foo(i32 %abc)
  169. %ab2 = add i32 %ab, %b
  170. %ab2c = add i32 %ab2, %c
  171. ; CHECK: %ab2c = add i32 %abc, %b
  172. call void @foo(i32 %ab2c)
  173. ; CHECK-NEXT: call void @foo(i32 %ab2c)
  174. %ab3 = add i32 %ab2, %b
  175. %ab3c = add i32 %ab3, %c
  176. ; CHECK-NEXT: %ab3c = add i32 %ab2c, %b
  177. call void @foo(i32 %ab3c)
  178. ; CHECK-NEXT: call void @foo(i32 %ab3c)
  179. ret void
  180. }
  181. define void @avoid_infinite_loop(i32 %a, i32 %b) {
  182. ; CHECK-LABEL: @avoid_infinite_loop
  183. %ab = add i32 %a, %b
  184. ; CHECK-NEXT: %ab
  185. %ab2 = add i32 %ab, %b
  186. ; CHECK-NEXT: %ab2
  187. call void @foo(i32 %ab2)
  188. ; CHECK-NEXT: @foo(i32 %ab2)
  189. ret void
  190. }