slsr-mul.ll 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. ; RUN: opt < %s -slsr -gvn -S | FileCheck %s
  2. target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
  3. define void @slsr1(i32 %b, i32 %s) {
  4. ; CHECK-LABEL: @slsr1(
  5. ; foo(b * s);
  6. %mul0 = mul i32 %b, %s
  7. ; CHECK: mul i32
  8. ; CHECK-NOT: mul i32
  9. call void @foo(i32 %mul0)
  10. ; foo((b + 1) * s);
  11. %b1 = add i32 %b, 1
  12. %mul1 = mul i32 %b1, %s
  13. call void @foo(i32 %mul1)
  14. ; foo((b + 2) * s);
  15. %b2 = add i32 %b, 2
  16. %mul2 = mul i32 %b2, %s
  17. call void @foo(i32 %mul2)
  18. ret void
  19. }
  20. define void @non_canonicalized(i32 %b, i32 %s) {
  21. ; CHECK-LABEL: @non_canonicalized(
  22. ; foo(b * s);
  23. %mul0 = mul i32 %b, %s
  24. ; CHECK: mul i32
  25. ; CHECK-NOT: mul i32
  26. call void @foo(i32 %mul0)
  27. ; foo((1 + b) * s);
  28. %b1 = add i32 1, %b
  29. %mul1 = mul i32 %b1, %s
  30. call void @foo(i32 %mul1)
  31. ; foo((2 + b) * s);
  32. %b2 = add i32 2, %b
  33. %mul2 = mul i32 %b2, %s
  34. call void @foo(i32 %mul2)
  35. ret void
  36. }
  37. define void @or(i32 %a, i32 %s) {
  38. %b = shl i32 %a, 1
  39. ; CHECK-LABEL: @or(
  40. ; foo(b * s);
  41. %mul0 = mul i32 %b, %s
  42. ; CHECK: [[base:[^ ]+]] = mul i32
  43. call void @foo(i32 %mul0)
  44. ; foo((b | 1) * s);
  45. %b1 = or i32 %b, 1
  46. %mul1 = mul i32 %b1, %s
  47. ; CHECK: add i32 [[base]], %s
  48. call void @foo(i32 %mul1)
  49. ; foo((b | 2) * s);
  50. %b2 = or i32 %b, 2
  51. %mul2 = mul i32 %b2, %s
  52. ; CHECK: mul i32 %b2, %s
  53. call void @foo(i32 %mul2)
  54. ret void
  55. }
  56. ; foo(a * b)
  57. ; foo((a + 1) * b)
  58. ; foo(a * (b + 1))
  59. ; foo((a + 1) * (b + 1))
  60. define void @slsr2(i32 %a, i32 %b) {
  61. ; CHECK-LABEL: @slsr2(
  62. %a1 = add i32 %a, 1
  63. %b1 = add i32 %b, 1
  64. %mul0 = mul i32 %a, %b
  65. ; CHECK: mul i32
  66. ; CHECK-NOT: mul i32
  67. %mul1 = mul i32 %a1, %b
  68. %mul2 = mul i32 %a, %b1
  69. %mul3 = mul i32 %a1, %b1
  70. call void @foo(i32 %mul0)
  71. call void @foo(i32 %mul1)
  72. call void @foo(i32 %mul2)
  73. call void @foo(i32 %mul3)
  74. ret void
  75. }
  76. ; The bump is a multiple of the stride.
  77. ;
  78. ; foo(b * s);
  79. ; foo((b + 2) * s);
  80. ; foo((b + 4) * s);
  81. ; =>
  82. ; mul0 = b * s;
  83. ; bump = s * 2;
  84. ; mul1 = mul0 + bump; // GVN ensures mul1 and mul2 use the same bump.
  85. ; mul2 = mul1 + bump;
  86. define void @slsr3(i32 %b, i32 %s) {
  87. ; CHECK-LABEL: @slsr3(
  88. %mul0 = mul i32 %b, %s
  89. ; CHECK: mul i32
  90. call void @foo(i32 %mul0)
  91. %b1 = add i32 %b, 2
  92. %mul1 = mul i32 %b1, %s
  93. ; CHECK: [[BUMP:%[a-zA-Z0-9]+]] = shl i32 %s, 1
  94. ; CHECK: %mul1 = add i32 %mul0, [[BUMP]]
  95. call void @foo(i32 %mul1)
  96. %b2 = add i32 %b, 4
  97. %mul2 = mul i32 %b2, %s
  98. ; CHECK: %mul2 = add i32 %mul1, [[BUMP]]
  99. call void @foo(i32 %mul2)
  100. ret void
  101. }
  102. ; Do not rewrite a candidate if its potential basis does not dominate it.
  103. ;
  104. ; if (cond)
  105. ; foo(a * b);
  106. ; foo((a + 1) * b);
  107. define void @not_dominate(i1 %cond, i32 %a, i32 %b) {
  108. ; CHECK-LABEL: @not_dominate(
  109. entry:
  110. %a1 = add i32 %a, 1
  111. br i1 %cond, label %then, label %merge
  112. then:
  113. %mul0 = mul i32 %a, %b
  114. ; CHECK: %mul0 = mul i32 %a, %b
  115. call void @foo(i32 %mul0)
  116. br label %merge
  117. merge:
  118. %mul1 = mul i32 %a1, %b
  119. ; CHECK: %mul1 = mul i32 %a1, %b
  120. call void @foo(i32 %mul1)
  121. ret void
  122. }
  123. declare void @foo(i32)