ScaledNumberTest.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. //===- llvm/unittest/Support/ScaledNumberTest.cpp - ScaledPair tests -----==//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/Support/ScaledNumber.h"
  10. #include "llvm/Support/DataTypes.h"
  11. #include "gtest/gtest.h"
  12. using namespace llvm;
  13. using namespace llvm::ScaledNumbers;
  14. namespace {
  15. template <class UIntT> struct ScaledPair {
  16. UIntT D;
  17. int S;
  18. ScaledPair(const std::pair<UIntT, int16_t> &F) : D(F.first), S(F.second) {}
  19. ScaledPair(UIntT D, int S) : D(D), S(S) {}
  20. bool operator==(const ScaledPair<UIntT> &X) const {
  21. return D == X.D && S == X.S;
  22. }
  23. };
  24. template <class UIntT>
  25. bool operator==(const std::pair<UIntT, int16_t> &L,
  26. const ScaledPair<UIntT> &R) {
  27. return ScaledPair<UIntT>(L) == R;
  28. }
  29. template <class UIntT>
  30. void PrintTo(const ScaledPair<UIntT> &F, ::std::ostream *os) {
  31. *os << F.D << "*2^" << F.S;
  32. }
  33. typedef ScaledPair<uint32_t> SP32;
  34. typedef ScaledPair<uint64_t> SP64;
  35. TEST(ScaledNumberHelpersTest, getRounded) {
  36. EXPECT_EQ(getRounded32(0, 0, false), SP32(0, 0));
  37. EXPECT_EQ(getRounded32(0, 0, true), SP32(1, 0));
  38. EXPECT_EQ(getRounded32(20, 21, true), SP32(21, 21));
  39. EXPECT_EQ(getRounded32(UINT32_MAX, 0, false), SP32(UINT32_MAX, 0));
  40. EXPECT_EQ(getRounded32(UINT32_MAX, 0, true), SP32(1 << 31, 1));
  41. EXPECT_EQ(getRounded64(0, 0, false), SP64(0, 0));
  42. EXPECT_EQ(getRounded64(0, 0, true), SP64(1, 0));
  43. EXPECT_EQ(getRounded64(20, 21, true), SP64(21, 21));
  44. EXPECT_EQ(getRounded64(UINT32_MAX, 0, false), SP64(UINT32_MAX, 0));
  45. EXPECT_EQ(getRounded64(UINT32_MAX, 0, true), SP64(UINT64_C(1) << 32, 0));
  46. EXPECT_EQ(getRounded64(UINT64_MAX, 0, false), SP64(UINT64_MAX, 0));
  47. EXPECT_EQ(getRounded64(UINT64_MAX, 0, true), SP64(UINT64_C(1) << 63, 1));
  48. }
  49. TEST(ScaledNumberHelpersTest, getAdjusted) {
  50. const uint64_t Max32In64 = UINT32_MAX;
  51. EXPECT_EQ(getAdjusted32(0), SP32(0, 0));
  52. EXPECT_EQ(getAdjusted32(0, 5), SP32(0, 5));
  53. EXPECT_EQ(getAdjusted32(UINT32_MAX), SP32(UINT32_MAX, 0));
  54. EXPECT_EQ(getAdjusted32(Max32In64 << 1), SP32(UINT32_MAX, 1));
  55. EXPECT_EQ(getAdjusted32(Max32In64 << 1, 1), SP32(UINT32_MAX, 2));
  56. EXPECT_EQ(getAdjusted32(Max32In64 << 31), SP32(UINT32_MAX, 31));
  57. EXPECT_EQ(getAdjusted32(Max32In64 << 32), SP32(UINT32_MAX, 32));
  58. EXPECT_EQ(getAdjusted32(Max32In64 + 1), SP32(1u << 31, 1));
  59. EXPECT_EQ(getAdjusted32(UINT64_MAX), SP32(1u << 31, 33));
  60. EXPECT_EQ(getAdjusted64(0), SP64(0, 0));
  61. EXPECT_EQ(getAdjusted64(0, 5), SP64(0, 5));
  62. EXPECT_EQ(getAdjusted64(UINT32_MAX), SP64(UINT32_MAX, 0));
  63. EXPECT_EQ(getAdjusted64(Max32In64 << 1), SP64(Max32In64 << 1, 0));
  64. EXPECT_EQ(getAdjusted64(Max32In64 << 1, 1), SP64(Max32In64 << 1, 1));
  65. EXPECT_EQ(getAdjusted64(Max32In64 << 31), SP64(Max32In64 << 31, 0));
  66. EXPECT_EQ(getAdjusted64(Max32In64 << 32), SP64(Max32In64 << 32, 0));
  67. EXPECT_EQ(getAdjusted64(Max32In64 + 1), SP64(Max32In64 + 1, 0));
  68. EXPECT_EQ(getAdjusted64(UINT64_MAX), SP64(UINT64_MAX, 0));
  69. }
  70. TEST(ScaledNumberHelpersTest, getProduct) {
  71. // Zero.
  72. EXPECT_EQ(SP32(0, 0), getProduct32(0, 0));
  73. EXPECT_EQ(SP32(0, 0), getProduct32(0, 1));
  74. EXPECT_EQ(SP32(0, 0), getProduct32(0, 33));
  75. // Basic.
  76. EXPECT_EQ(SP32(6, 0), getProduct32(2, 3));
  77. EXPECT_EQ(SP32(UINT16_MAX / 3 * UINT16_MAX / 5 * 2, 0),
  78. getProduct32(UINT16_MAX / 3, UINT16_MAX / 5 * 2));
  79. // Overflow, no loss of precision.
  80. // ==> 0xf00010 * 0x1001
  81. // ==> 0xf00f00000 + 0x10010
  82. // ==> 0xf00f10010
  83. // ==> 0xf00f1001 * 2^4
  84. EXPECT_EQ(SP32(0xf00f1001, 4), getProduct32(0xf00010, 0x1001));
  85. // Overflow, loss of precision, rounds down.
  86. // ==> 0xf000070 * 0x1001
  87. // ==> 0xf00f000000 + 0x70070
  88. // ==> 0xf00f070070
  89. // ==> 0xf00f0700 * 2^8
  90. EXPECT_EQ(SP32(0xf00f0700, 8), getProduct32(0xf000070, 0x1001));
  91. // Overflow, loss of precision, rounds up.
  92. // ==> 0xf000080 * 0x1001
  93. // ==> 0xf00f000000 + 0x80080
  94. // ==> 0xf00f080080
  95. // ==> 0xf00f0801 * 2^8
  96. EXPECT_EQ(SP32(0xf00f0801, 8), getProduct32(0xf000080, 0x1001));
  97. // Reverse operand order.
  98. EXPECT_EQ(SP32(0, 0), getProduct32(1, 0));
  99. EXPECT_EQ(SP32(0, 0), getProduct32(33, 0));
  100. EXPECT_EQ(SP32(6, 0), getProduct32(3, 2));
  101. EXPECT_EQ(SP32(UINT16_MAX / 3 * UINT16_MAX / 5 * 2, 0),
  102. getProduct32(UINT16_MAX / 5 * 2, UINT16_MAX / 3));
  103. EXPECT_EQ(SP32(0xf00f1001, 4), getProduct32(0x1001, 0xf00010));
  104. EXPECT_EQ(SP32(0xf00f0700, 8), getProduct32(0x1001, 0xf000070));
  105. EXPECT_EQ(SP32(0xf00f0801, 8), getProduct32(0x1001, 0xf000080));
  106. // Round to overflow.
  107. EXPECT_EQ(SP64(UINT64_C(1) << 63, 64),
  108. getProduct64(UINT64_C(10376293541461622786),
  109. UINT64_C(16397105843297379211)));
  110. // Big number with rounding.
  111. EXPECT_EQ(SP64(UINT64_C(9223372036854775810), 64),
  112. getProduct64(UINT64_C(18446744073709551556),
  113. UINT64_C(9223372036854775840)));
  114. }
  115. TEST(ScaledNumberHelpersTest, getQuotient) {
  116. // Zero.
  117. EXPECT_EQ(SP32(0, 0), getQuotient32(0, 0));
  118. EXPECT_EQ(SP32(0, 0), getQuotient32(0, 1));
  119. EXPECT_EQ(SP32(0, 0), getQuotient32(0, 73));
  120. EXPECT_EQ(SP32(UINT32_MAX, INT16_MAX), getQuotient32(1, 0));
  121. EXPECT_EQ(SP32(UINT32_MAX, INT16_MAX), getQuotient32(6, 0));
  122. // Powers of two.
  123. EXPECT_EQ(SP32(1u << 31, -31), getQuotient32(1, 1));
  124. EXPECT_EQ(SP32(1u << 31, -30), getQuotient32(2, 1));
  125. EXPECT_EQ(SP32(1u << 31, -33), getQuotient32(4, 16));
  126. EXPECT_EQ(SP32(7u << 29, -29), getQuotient32(7, 1));
  127. EXPECT_EQ(SP32(7u << 29, -30), getQuotient32(7, 2));
  128. EXPECT_EQ(SP32(7u << 29, -33), getQuotient32(7, 16));
  129. // Divide evenly.
  130. EXPECT_EQ(SP32(3u << 30, -30), getQuotient32(9, 3));
  131. EXPECT_EQ(SP32(9u << 28, -28), getQuotient32(63, 7));
  132. // Divide unevenly.
  133. EXPECT_EQ(SP32(0xaaaaaaab, -33), getQuotient32(1, 3));
  134. EXPECT_EQ(SP32(0xd5555555, -31), getQuotient32(5, 3));
  135. // 64-bit division is hard to test, since divide64 doesn't canonicalized its
  136. // output. However, this is the algorithm the implementation uses:
  137. //
  138. // - Shift divisor right.
  139. // - If we have 1 (power of 2), return early -- not canonicalized.
  140. // - Shift dividend left.
  141. // - 64-bit integer divide.
  142. // - If there's a remainder, continue with long division.
  143. //
  144. // TODO: require less knowledge about the implementation in the test.
  145. // Zero.
  146. EXPECT_EQ(SP64(0, 0), getQuotient64(0, 0));
  147. EXPECT_EQ(SP64(0, 0), getQuotient64(0, 1));
  148. EXPECT_EQ(SP64(0, 0), getQuotient64(0, 73));
  149. EXPECT_EQ(SP64(UINT64_MAX, INT16_MAX), getQuotient64(1, 0));
  150. EXPECT_EQ(SP64(UINT64_MAX, INT16_MAX), getQuotient64(6, 0));
  151. // Powers of two.
  152. EXPECT_EQ(SP64(1, 0), getQuotient64(1, 1));
  153. EXPECT_EQ(SP64(2, 0), getQuotient64(2, 1));
  154. EXPECT_EQ(SP64(4, -4), getQuotient64(4, 16));
  155. EXPECT_EQ(SP64(7, 0), getQuotient64(7, 1));
  156. EXPECT_EQ(SP64(7, -1), getQuotient64(7, 2));
  157. EXPECT_EQ(SP64(7, -4), getQuotient64(7, 16));
  158. // Divide evenly.
  159. EXPECT_EQ(SP64(UINT64_C(3) << 60, -60), getQuotient64(9, 3));
  160. EXPECT_EQ(SP64(UINT64_C(9) << 58, -58), getQuotient64(63, 7));
  161. // Divide unevenly.
  162. EXPECT_EQ(SP64(0xaaaaaaaaaaaaaaab, -65), getQuotient64(1, 3));
  163. EXPECT_EQ(SP64(0xd555555555555555, -63), getQuotient64(5, 3));
  164. }
  165. TEST(ScaledNumberHelpersTest, getLg) {
  166. EXPECT_EQ(0, getLg(UINT32_C(1), 0));
  167. EXPECT_EQ(1, getLg(UINT32_C(1), 1));
  168. EXPECT_EQ(1, getLg(UINT32_C(2), 0));
  169. EXPECT_EQ(3, getLg(UINT32_C(1), 3));
  170. EXPECT_EQ(3, getLg(UINT32_C(7), 0));
  171. EXPECT_EQ(3, getLg(UINT32_C(8), 0));
  172. EXPECT_EQ(3, getLg(UINT32_C(9), 0));
  173. EXPECT_EQ(3, getLg(UINT32_C(64), -3));
  174. EXPECT_EQ(31, getLg((UINT32_MAX >> 1) + 2, 0));
  175. EXPECT_EQ(32, getLg(UINT32_MAX, 0));
  176. EXPECT_EQ(-1, getLg(UINT32_C(1), -1));
  177. EXPECT_EQ(-1, getLg(UINT32_C(2), -2));
  178. EXPECT_EQ(INT32_MIN, getLg(UINT32_C(0), -1));
  179. EXPECT_EQ(INT32_MIN, getLg(UINT32_C(0), 0));
  180. EXPECT_EQ(INT32_MIN, getLg(UINT32_C(0), 1));
  181. EXPECT_EQ(0, getLg(UINT64_C(1), 0));
  182. EXPECT_EQ(1, getLg(UINT64_C(1), 1));
  183. EXPECT_EQ(1, getLg(UINT64_C(2), 0));
  184. EXPECT_EQ(3, getLg(UINT64_C(1), 3));
  185. EXPECT_EQ(3, getLg(UINT64_C(7), 0));
  186. EXPECT_EQ(3, getLg(UINT64_C(8), 0));
  187. EXPECT_EQ(3, getLg(UINT64_C(9), 0));
  188. EXPECT_EQ(3, getLg(UINT64_C(64), -3));
  189. EXPECT_EQ(63, getLg((UINT64_MAX >> 1) + 2, 0));
  190. EXPECT_EQ(64, getLg(UINT64_MAX, 0));
  191. EXPECT_EQ(-1, getLg(UINT64_C(1), -1));
  192. EXPECT_EQ(-1, getLg(UINT64_C(2), -2));
  193. EXPECT_EQ(INT32_MIN, getLg(UINT64_C(0), -1));
  194. EXPECT_EQ(INT32_MIN, getLg(UINT64_C(0), 0));
  195. EXPECT_EQ(INT32_MIN, getLg(UINT64_C(0), 1));
  196. }
  197. TEST(ScaledNumberHelpersTest, getLgFloor) {
  198. EXPECT_EQ(0, getLgFloor(UINT32_C(1), 0));
  199. EXPECT_EQ(1, getLgFloor(UINT32_C(1), 1));
  200. EXPECT_EQ(1, getLgFloor(UINT32_C(2), 0));
  201. EXPECT_EQ(2, getLgFloor(UINT32_C(7), 0));
  202. EXPECT_EQ(3, getLgFloor(UINT32_C(1), 3));
  203. EXPECT_EQ(3, getLgFloor(UINT32_C(8), 0));
  204. EXPECT_EQ(3, getLgFloor(UINT32_C(9), 0));
  205. EXPECT_EQ(3, getLgFloor(UINT32_C(64), -3));
  206. EXPECT_EQ(31, getLgFloor((UINT32_MAX >> 1) + 2, 0));
  207. EXPECT_EQ(31, getLgFloor(UINT32_MAX, 0));
  208. EXPECT_EQ(INT32_MIN, getLgFloor(UINT32_C(0), -1));
  209. EXPECT_EQ(INT32_MIN, getLgFloor(UINT32_C(0), 0));
  210. EXPECT_EQ(INT32_MIN, getLgFloor(UINT32_C(0), 1));
  211. EXPECT_EQ(0, getLgFloor(UINT64_C(1), 0));
  212. EXPECT_EQ(1, getLgFloor(UINT64_C(1), 1));
  213. EXPECT_EQ(1, getLgFloor(UINT64_C(2), 0));
  214. EXPECT_EQ(2, getLgFloor(UINT64_C(7), 0));
  215. EXPECT_EQ(3, getLgFloor(UINT64_C(1), 3));
  216. EXPECT_EQ(3, getLgFloor(UINT64_C(8), 0));
  217. EXPECT_EQ(3, getLgFloor(UINT64_C(9), 0));
  218. EXPECT_EQ(3, getLgFloor(UINT64_C(64), -3));
  219. EXPECT_EQ(63, getLgFloor((UINT64_MAX >> 1) + 2, 0));
  220. EXPECT_EQ(63, getLgFloor(UINT64_MAX, 0));
  221. EXPECT_EQ(INT32_MIN, getLgFloor(UINT64_C(0), -1));
  222. EXPECT_EQ(INT32_MIN, getLgFloor(UINT64_C(0), 0));
  223. EXPECT_EQ(INT32_MIN, getLgFloor(UINT64_C(0), 1));
  224. }
  225. TEST(ScaledNumberHelpersTest, getLgCeiling) {
  226. EXPECT_EQ(0, getLgCeiling(UINT32_C(1), 0));
  227. EXPECT_EQ(1, getLgCeiling(UINT32_C(1), 1));
  228. EXPECT_EQ(1, getLgCeiling(UINT32_C(2), 0));
  229. EXPECT_EQ(3, getLgCeiling(UINT32_C(1), 3));
  230. EXPECT_EQ(3, getLgCeiling(UINT32_C(7), 0));
  231. EXPECT_EQ(3, getLgCeiling(UINT32_C(8), 0));
  232. EXPECT_EQ(3, getLgCeiling(UINT32_C(64), -3));
  233. EXPECT_EQ(4, getLgCeiling(UINT32_C(9), 0));
  234. EXPECT_EQ(32, getLgCeiling(UINT32_MAX, 0));
  235. EXPECT_EQ(32, getLgCeiling((UINT32_MAX >> 1) + 2, 0));
  236. EXPECT_EQ(INT32_MIN, getLgCeiling(UINT32_C(0), -1));
  237. EXPECT_EQ(INT32_MIN, getLgCeiling(UINT32_C(0), 0));
  238. EXPECT_EQ(INT32_MIN, getLgCeiling(UINT32_C(0), 1));
  239. EXPECT_EQ(0, getLgCeiling(UINT64_C(1), 0));
  240. EXPECT_EQ(1, getLgCeiling(UINT64_C(1), 1));
  241. EXPECT_EQ(1, getLgCeiling(UINT64_C(2), 0));
  242. EXPECT_EQ(3, getLgCeiling(UINT64_C(1), 3));
  243. EXPECT_EQ(3, getLgCeiling(UINT64_C(7), 0));
  244. EXPECT_EQ(3, getLgCeiling(UINT64_C(8), 0));
  245. EXPECT_EQ(3, getLgCeiling(UINT64_C(64), -3));
  246. EXPECT_EQ(4, getLgCeiling(UINT64_C(9), 0));
  247. EXPECT_EQ(64, getLgCeiling((UINT64_MAX >> 1) + 2, 0));
  248. EXPECT_EQ(64, getLgCeiling(UINT64_MAX, 0));
  249. EXPECT_EQ(INT32_MIN, getLgCeiling(UINT64_C(0), -1));
  250. EXPECT_EQ(INT32_MIN, getLgCeiling(UINT64_C(0), 0));
  251. EXPECT_EQ(INT32_MIN, getLgCeiling(UINT64_C(0), 1));
  252. }
  253. TEST(ScaledNumberHelpersTest, Compare) {
  254. EXPECT_EQ(0, compare(UINT32_C(0), 0, UINT32_C(0), 1));
  255. EXPECT_EQ(0, compare(UINT32_C(0), 0, UINT32_C(0), -10));
  256. EXPECT_EQ(0, compare(UINT32_C(0), 0, UINT32_C(0), 20));
  257. EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(64), -3));
  258. EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(32), -2));
  259. EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(16), -1));
  260. EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(8), 0));
  261. EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(4), 1));
  262. EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(2), 2));
  263. EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(1), 3));
  264. EXPECT_EQ(-1, compare(UINT32_C(0), 0, UINT32_C(1), 3));
  265. EXPECT_EQ(-1, compare(UINT32_C(7), 0, UINT32_C(1), 3));
  266. EXPECT_EQ(-1, compare(UINT32_C(7), 0, UINT32_C(64), -3));
  267. EXPECT_EQ(1, compare(UINT32_C(9), 0, UINT32_C(1), 3));
  268. EXPECT_EQ(1, compare(UINT32_C(9), 0, UINT32_C(64), -3));
  269. EXPECT_EQ(1, compare(UINT32_C(9), 0, UINT32_C(0), 0));
  270. EXPECT_EQ(0, compare(UINT64_C(0), 0, UINT64_C(0), 1));
  271. EXPECT_EQ(0, compare(UINT64_C(0), 0, UINT64_C(0), -10));
  272. EXPECT_EQ(0, compare(UINT64_C(0), 0, UINT64_C(0), 20));
  273. EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(64), -3));
  274. EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(32), -2));
  275. EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(16), -1));
  276. EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(8), 0));
  277. EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(4), 1));
  278. EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(2), 2));
  279. EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(1), 3));
  280. EXPECT_EQ(-1, compare(UINT64_C(0), 0, UINT64_C(1), 3));
  281. EXPECT_EQ(-1, compare(UINT64_C(7), 0, UINT64_C(1), 3));
  282. EXPECT_EQ(-1, compare(UINT64_C(7), 0, UINT64_C(64), -3));
  283. EXPECT_EQ(1, compare(UINT64_C(9), 0, UINT64_C(1), 3));
  284. EXPECT_EQ(1, compare(UINT64_C(9), 0, UINT64_C(64), -3));
  285. EXPECT_EQ(1, compare(UINT64_C(9), 0, UINT64_C(0), 0));
  286. EXPECT_EQ(-1, compare(UINT64_MAX, 0, UINT64_C(1), 64));
  287. }
  288. } // end namespace