xor_reassoc.ll 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. ;RUN: opt -S -reassociate < %s | FileCheck %s
  2. ; ==========================================================================
  3. ;
  4. ; Xor reassociation general cases
  5. ;
  6. ; ==========================================================================
  7. ; (x | c1) ^ (x | c2) => (x & c3) ^ c3, where c3 = c1^c2
  8. ;
  9. define i32 @xor1(i32 %x) {
  10. %or = or i32 %x, 123
  11. %or1 = or i32 %x, 456
  12. %xor = xor i32 %or, %or1
  13. ret i32 %xor
  14. ;CHECK-LABEL: @xor1(
  15. ;CHECK: %and.ra = and i32 %x, 435
  16. ;CHECK: %xor = xor i32 %and.ra, 435
  17. }
  18. ; Test rule : (x & c1) ^ (x & c2) = (x & (c1^c2))
  19. ; Real testing case : (x & 123) ^ y ^ (x & 345) => (x & 435) ^ y
  20. define i32 @xor2(i32 %x, i32 %y) {
  21. %and = and i32 %x, 123
  22. %xor = xor i32 %and, %y
  23. %and1 = and i32 %x, 456
  24. %xor2 = xor i32 %xor, %and1
  25. ret i32 %xor2
  26. ;CHECK-LABEL: @xor2(
  27. ;CHECK: %and.ra = and i32 %x, 435
  28. ;CHECK: %xor2 = xor i32 %and.ra, %y
  29. }
  30. ; Test rule: (x | c1) ^ (x & c2) = (x & c3) ^ c1, where c3 = ~c1 ^ c2
  31. ; c3 = ~c1 ^ c2
  32. define i32 @xor3(i32 %x, i32 %y) {
  33. %or = or i32 %x, 123
  34. %xor = xor i32 %or, %y
  35. %and = and i32 %x, 456
  36. %xor1 = xor i32 %xor, %and
  37. ret i32 %xor1
  38. ;CHECK-LABEL: @xor3(
  39. ;CHECK: %and.ra = and i32 %x, -436
  40. ;CHECK: %xor = xor i32 %y, 123
  41. ;CHECK: %xor1 = xor i32 %xor, %and.ra
  42. }
  43. ; Test rule: (x | c1) ^ c2 = (x & ~c1) ^ (c1 ^ c2)
  44. define i32 @xor4(i32 %x, i32 %y) {
  45. %and = and i32 %x, -124
  46. %xor = xor i32 %y, 435
  47. %xor1 = xor i32 %xor, %and
  48. ret i32 %xor1
  49. ; CHECK-LABEL: @xor4(
  50. ; CHECK: %and = and i32 %x, -124
  51. ; CHECK: %xor = xor i32 %y, 435
  52. ; CHECK: %xor1 = xor i32 %xor, %and
  53. }
  54. ; ==========================================================================
  55. ;
  56. ; Xor reassociation special cases
  57. ;
  58. ; ==========================================================================
  59. ; Special case1:
  60. ; (x | c1) ^ (x & ~c1) = c1
  61. define i32 @xor_special1(i32 %x, i32 %y) {
  62. %or = or i32 %x, 123
  63. %xor = xor i32 %or, %y
  64. %and = and i32 %x, -124
  65. %xor1 = xor i32 %xor, %and
  66. ret i32 %xor1
  67. ; CHECK-LABEL: @xor_special1(
  68. ; CHECK: %xor1 = xor i32 %y, 123
  69. ; CHECK: ret i32 %xor1
  70. }
  71. ; Special case1:
  72. ; (x | c1) ^ (x & c1) = x ^ c1
  73. define i32 @xor_special2(i32 %x, i32 %y) {
  74. %or = or i32 %x, 123
  75. %xor = xor i32 %or, %y
  76. %and = and i32 %x, 123
  77. %xor1 = xor i32 %xor, %and
  78. ret i32 %xor1
  79. ; CHECK-LABEL: @xor_special2(
  80. ; CHECK: %xor = xor i32 %y, 123
  81. ; CHECK: %xor1 = xor i32 %xor, %x
  82. ; CHECK: ret i32 %xor1
  83. }
  84. ; (x | c1) ^ (x | c1) => 0
  85. define i32 @xor_special3(i32 %x) {
  86. %or = or i32 %x, 123
  87. %or1 = or i32 %x, 123
  88. %xor = xor i32 %or, %or1
  89. ret i32 %xor
  90. ;CHECK-LABEL: @xor_special3(
  91. ;CHECK: ret i32 0
  92. }
  93. ; (x & c1) ^ (x & c1) => 0
  94. define i32 @xor_special4(i32 %x) {
  95. %or = and i32 %x, 123
  96. %or1 = and i32 123, %x
  97. %xor = xor i32 %or, %or1
  98. ret i32 %xor
  99. ;CHECK-LABEL: @xor_special4(
  100. ;CHECK: ret i32 0
  101. }
  102. ; ==========================================================================
  103. ;
  104. ; Xor reassociation curtail code size
  105. ;
  106. ; ==========================================================================
  107. ; (x | c1) ^ (x | c2) => (x & c3) ^ c3
  108. ; is enabled if one of operands has multiple uses
  109. ;
  110. define i32 @xor_ra_size1(i32 %x) {
  111. %or = or i32 %x, 123
  112. %or1 = or i32 %x, 456
  113. %xor = xor i32 %or, %or1
  114. %add = add i32 %xor, %or
  115. ret i32 %add
  116. ;CHECK-LABEL: @xor_ra_size1(
  117. ;CHECK: %xor = xor i32 %and.ra, 435
  118. }
  119. ; (x | c1) ^ (x | c2) => (x & c3) ^ c3
  120. ; is disenabled if bothf operands has multiple uses.
  121. ;
  122. define i32 @xor_ra_size2(i32 %x) {
  123. %or = or i32 %x, 123
  124. %or1 = or i32 %x, 456
  125. %xor = xor i32 %or, %or1
  126. %add = add i32 %xor, %or
  127. %add2 = add i32 %add, %or1
  128. ret i32 %add2
  129. ;CHECK-LABEL: @xor_ra_size2(
  130. ;CHECK: %or1 = or i32 %x, 456
  131. ;CHECK: %xor = xor i32 %or, %or1
  132. }
  133. ; ==========================================================================
  134. ;
  135. ; Xor reassociation bugs
  136. ;
  137. ; ==========================================================================
  138. @xor_bug1_data = external global <{}>, align 4
  139. define void @xor_bug1() {
  140. %1 = ptrtoint i32* undef to i64
  141. %2 = xor i64 %1, ptrtoint (<{}>* @xor_bug1_data to i64)
  142. %3 = and i64 undef, %2
  143. ret void
  144. }
  145. ; The bug was that when the compiler optimize "(x | c1)" ^ "(x & c2)", it may
  146. ; swap the two xor-subexpressions if they are not in canoninical order; however,
  147. ; when optimizer swaps two sub-expressions, if forgot to swap the cached value
  148. ; of c1 and c2 accordingly, hence cause the problem.
  149. ;
  150. define i32 @xor_bug2(i32, i32, i32, i32) {
  151. %5 = mul i32 %0, 123
  152. %6 = add i32 %2, 24
  153. %7 = add i32 %1, 8
  154. %8 = and i32 %1, 3456789
  155. %9 = or i32 %8, 4567890
  156. %10 = and i32 %1, 543210987
  157. %11 = or i32 %1, 891034567
  158. %12 = and i32 %2, 255
  159. %13 = xor i32 %9, %10
  160. %14 = xor i32 %11, %13
  161. %15 = xor i32 %5, %14
  162. %16 = and i32 %3, 255
  163. %17 = xor i32 %16, 42
  164. %18 = add i32 %6, %7
  165. %19 = add i32 %18, %12
  166. %20 = add i32 %19, %15
  167. ret i32 %20
  168. ;CHECK-LABEL: @xor_bug2(
  169. ;CHECK: xor i32 %5, 891034567
  170. }