fast-ReassociateVector.ll 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. ; RUN: opt < %s -reassociate -S | FileCheck %s
  2. ; Check that a*c+b*c is turned into (a+b)*c
  3. define <4 x float> @test1(<4 x float> %a, <4 x float> %b, <4 x float> %c) {
  4. ; CHECK-LABEL: @test1
  5. ; CHECK-NEXT: %tmp = fadd fast <4 x float> %b, %a
  6. ; CHECK-NEXT: %tmp1 = fmul fast <4 x float> %tmp, %c
  7. ; CHECK-NEXT: ret <4 x float> %tmp1
  8. %mul = fmul fast <4 x float> %a, %c
  9. %mul1 = fmul fast <4 x float> %b, %c
  10. %add = fadd fast <4 x float> %mul, %mul1
  11. ret <4 x float> %add
  12. }
  13. ; Check that a*a*b+a*a*c is turned into a*(a*(b+c)).
  14. define <2 x float> @test2(<2 x float> %a, <2 x float> %b, <2 x float> %c) {
  15. ; CHECK-LABEL: @test2
  16. ; CHECK-NEXT: fadd fast <2 x float> %c, %b
  17. ; CHECK-NEXT: fmul fast <2 x float> %a, %tmp2
  18. ; CHECK-NEXT: fmul fast <2 x float> %tmp3, %a
  19. ; CHECK-NEXT: ret <2 x float>
  20. %t0 = fmul fast <2 x float> %a, %b
  21. %t1 = fmul fast <2 x float> %a, %t0
  22. %t2 = fmul fast <2 x float> %a, %c
  23. %t3 = fmul fast <2 x float> %a, %t2
  24. %t4 = fadd fast <2 x float> %t1, %t3
  25. ret <2 x float> %t4
  26. }
  27. ; Check that a*b+a*c+d is turned into a*(b+c)+d.
  28. define <2 x double> @test3(<2 x double> %a, <2 x double> %b, <2 x double> %c, <2 x double> %d) {
  29. ; CHECK-LABEL: @test3
  30. ; CHECK-NEXT: fadd fast <2 x double> %c, %b
  31. ; CHECK-NEXT: fmul fast <2 x double> %tmp, %a
  32. ; CHECK-NEXT: fadd fast <2 x double> %tmp1, %d
  33. ; CHECK-NEXT: ret <2 x double>
  34. %t0 = fmul fast <2 x double> %a, %b
  35. %t1 = fmul fast <2 x double> %a, %c
  36. %t2 = fadd fast <2 x double> %t1, %d
  37. %t3 = fadd fast <2 x double> %t0, %t2
  38. ret <2 x double> %t3
  39. }
  40. ; No fast-math.
  41. define <2 x float> @test4(<2 x float> %A) {
  42. ; CHECK-LABEL: @test4
  43. ; CHECK-NEXT: %X = fadd <2 x float> %A, <float 1.000000e+00, float 1.000000e+00>
  44. ; CHECK-NEXT: %Y = fadd <2 x float> %A, <float 1.000000e+00, float 1.000000e+00>
  45. ; CHECK-NEXT: %R = fsub <2 x float> %X, %Y
  46. ; CHECK-NEXT: ret <2 x float> %R
  47. %X = fadd <2 x float> %A, < float 1.000000e+00, float 1.000000e+00 >
  48. %Y = fadd <2 x float> %A, < float 1.000000e+00, float 1.000000e+00 >
  49. %R = fsub <2 x float> %X, %Y
  50. ret <2 x float> %R
  51. }
  52. ; Check 47*X + 47*X -> 94*X.
  53. define <2 x float> @test5(<2 x float> %X) {
  54. ; CHECK-LABEL: @test5
  55. ; CHECK-NEXT: fmul fast <2 x float> %X, <float 9.400000e+01, float 9.400000e+01>
  56. ; CHECK-NEXT: ret <2 x float>
  57. %Y = fmul fast <2 x float> %X, <float 4.700000e+01, float 4.700000e+01>
  58. %Z = fadd fast <2 x float> %Y, %Y
  59. ret <2 x float> %Z
  60. }
  61. ; Check X+X+X -> 3*X.
  62. define <2 x float> @test6(<2 x float> %X) {
  63. ; CHECK-LABEL: @test6
  64. ; CHECK-NEXT: fmul fast <2 x float> %X, <float 3.000000e+00, float 3.000000e+00>
  65. ; CHECK-NEXT: ret <2 x float>
  66. %Y = fadd fast <2 x float> %X ,%X
  67. %Z = fadd fast <2 x float> %Y, %X
  68. ret <2 x float> %Z
  69. }
  70. ; Check 127*W+50*W -> 177*W.
  71. define <2 x double> @test7(<2 x double> %W) {
  72. ; CHECK-LABEL: @test7
  73. ; CHECK-NEXT: fmul fast <2 x double> %W, <double 1.770000e+02, double 1.770000e+02>
  74. ; CHECK-NEXT: ret <2 x double>
  75. %X = fmul fast <2 x double> %W, <double 127.0, double 127.0>
  76. %Y = fmul fast <2 x double> %W, <double 50.0, double 50.0>
  77. %Z = fadd fast <2 x double> %Y, %X
  78. ret <2 x double> %Z
  79. }
  80. ; Check X*12*12 -> X*144.
  81. define <2 x float> @test8(<2 x float> %arg) {
  82. ; CHECK-LABEL: @test8
  83. ; CHECK: fmul fast <2 x float> %arg, <float 1.440000e+02, float 1.440000e+02>
  84. ; CHECK-NEXT: ret <2 x float> %tmp2
  85. %tmp1 = fmul fast <2 x float> <float 1.200000e+01, float 1.200000e+01>, %arg
  86. %tmp2 = fmul fast <2 x float> %tmp1, <float 1.200000e+01, float 1.200000e+01>
  87. ret <2 x float> %tmp2
  88. }
  89. ; Check (b+(a+1234))+-a -> b+1234.
  90. define <2 x double> @test9(<2 x double> %b, <2 x double> %a) {
  91. ; CHECK-LABEL: @test9
  92. ; CHECK: fadd fast <2 x double> %b, <double 1.234000e+03, double 1.234000e+03>
  93. ; CHECK-NEXT: ret <2 x double>
  94. %1 = fadd fast <2 x double> %a, <double 1.234000e+03, double 1.234000e+03>
  95. %2 = fadd fast <2 x double> %b, %1
  96. %3 = fsub fast <2 x double> <double 0.000000e+00, double 0.000000e+00>, %a
  97. %4 = fadd fast <2 x double> %2, %3
  98. ret <2 x double> %4
  99. }
  100. ; Check -(-(z*40)*a) -> a*40*z.
  101. define <2 x float> @test10(<2 x float> %a, <2 x float> %b, <2 x float> %z) {
  102. ; CHECK-LABEL: @test10
  103. ; CHECK: fmul fast <2 x float> %a, <float 4.000000e+01, float 4.000000e+01>
  104. ; CHECK-NEXT: fmul fast <2 x float> %e, %z
  105. ; CHECK-NEXT: ret <2 x float>
  106. %d = fmul fast <2 x float> %z, <float 4.000000e+01, float 4.000000e+01>
  107. %c = fsub fast <2 x float> <float 0.000000e+00, float 0.000000e+00>, %d
  108. %e = fmul fast <2 x float> %a, %c
  109. %f = fsub fast <2 x float> <float 0.000000e+00, float 0.000000e+00>, %e
  110. ret <2 x float> %f
  111. }
  112. ; Check x*y+y*x -> x*y*2.
  113. define <2 x double> @test11(<2 x double> %x, <2 x double> %y) {
  114. ; CHECK-LABEL: @test11
  115. ; CHECK-NEXT: %factor = fmul fast <2 x double> %y, <double 2.000000e+00, double 2.000000e+00>
  116. ; CHECK-NEXT: %tmp1 = fmul fast <2 x double> %factor, %x
  117. ; CHECK-NEXT: ret <2 x double> %tmp1
  118. %1 = fmul fast <2 x double> %x, %y
  119. %2 = fmul fast <2 x double> %y, %x
  120. %3 = fadd fast <2 x double> %1, %2
  121. ret <2 x double> %3
  122. }
  123. ; FIXME: shifts should be converted to mul to assist further reassociation.
  124. define <2 x i64> @test12(<2 x i64> %b, <2 x i64> %c) {
  125. ; CHECK-LABEL: @test12
  126. ; CHECK-NEXT: %mul = mul <2 x i64> %c, %b
  127. ; CHECK-NEXT: %shl = shl <2 x i64> %mul, <i64 5, i64 5>
  128. ; CHECK-NEXT: ret <2 x i64> %shl
  129. %mul = mul <2 x i64> %c, %b
  130. %shl = shl <2 x i64> %mul, <i64 5, i64 5>
  131. ret <2 x i64> %shl
  132. }
  133. ; FIXME: expressions with a negative const should be canonicalized to assist
  134. ; further reassociation.
  135. ; We would expect (-5*b)+a -> a-(5*b) but only the constant operand is commuted.
  136. define <4 x float> @test13(<4 x float> %a, <4 x float> %b) {
  137. ; CHECK-LABEL: @test13
  138. ; CHECK-NEXT: %mul = fmul fast <4 x float> %b, <float -5.000000e+00, float -5.000000e+00, float -5.000000e+00, float -5.000000e+00>
  139. ; CHECK-NEXT: %add = fadd fast <4 x float> %mul, %a
  140. ; CHECK-NEXT: ret <4 x float> %add
  141. %mul = fmul fast <4 x float> <float -5.000000e+00, float -5.000000e+00, float -5.000000e+00, float -5.000000e+00>, %b
  142. %add = fadd fast <4 x float> %mul, %a
  143. ret <4 x float> %add
  144. }
  145. ; Break up subtract to assist further reassociation.
  146. ; Check a+b-c -> a+b+-c.
  147. define <2 x i64> @test14(<2 x i64> %a, <2 x i64> %b, <2 x i64> %c) {
  148. ; CHECK-LABEL: @test14
  149. ; CHECK-NEXT: %add = add <2 x i64> %b, %a
  150. ; CHECK-NEXT: %c.neg = sub <2 x i64> zeroinitializer, %c
  151. ; CHECK-NEXT: %sub = add <2 x i64> %add, %c.neg
  152. ; CHECK-NEXT: ret <2 x i64> %sub
  153. %add = add <2 x i64> %b, %a
  154. %sub = sub <2 x i64> %add, %c
  155. ret <2 x i64> %sub
  156. }
  157. define <2 x i32> @test15(<2 x i32> %x, <2 x i32> %y) {
  158. ; CHECK-LABEL: test15
  159. ; CHECK-NEXT: %tmp3 = and <2 x i32> %y, %x
  160. ; CHECK-NEXT: ret <2 x i32> %tmp3
  161. %tmp1 = and <2 x i32> %x, %y
  162. %tmp2 = and <2 x i32> %y, %x
  163. %tmp3 = and <2 x i32> %tmp1, %tmp2
  164. ret <2 x i32> %tmp3
  165. }
  166. define <2 x i32> @test16(<2 x i32> %x, <2 x i32> %y) {
  167. ; CHECK-LABEL: test16
  168. ; CHECK-NEXT: %tmp3 = or <2 x i32> %y, %x
  169. ; CHECK-NEXT: ret <2 x i32> %tmp3
  170. %tmp1 = or <2 x i32> %x, %y
  171. %tmp2 = or <2 x i32> %y, %x
  172. %tmp3 = or <2 x i32> %tmp1, %tmp2
  173. ret <2 x i32> %tmp3
  174. }
  175. ; FIXME: Optimize vector xor. Currently only commute operands.
  176. define <2 x i32> @test17(<2 x i32> %x, <2 x i32> %y) {
  177. ; CHECK-LABEL: test17
  178. ; CHECK-NEXT: %tmp1 = xor <2 x i32> %x, %y
  179. ; CHECK-NEXT: %tmp2 = xor <2 x i32> %x, %y
  180. ; CHECK-NEXT: %tmp3 = xor <2 x i32> %tmp1, %tmp2
  181. %tmp1 = xor <2 x i32> %x, %y
  182. %tmp2 = xor <2 x i32> %y, %x
  183. %tmp3 = xor <2 x i32> %tmp1, %tmp2
  184. ret <2 x i32> %tmp3
  185. }