xref: /llvm-project/libc/test/src/__support/HashTable/group_test.cpp (revision e59582b6f8f1be3e675866f6a5d661eb4c8ed448)
181e3e7e5SSchrodinger ZHU Yifan //===-- Unittests for control group ---------------------------------------===//
281e3e7e5SSchrodinger ZHU Yifan //
381e3e7e5SSchrodinger ZHU Yifan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481e3e7e5SSchrodinger ZHU Yifan // See https://llvm.org/LICENSE.txt for license information.
581e3e7e5SSchrodinger ZHU Yifan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681e3e7e5SSchrodinger ZHU Yifan //
781e3e7e5SSchrodinger ZHU Yifan //===----------------------------------------------------------------------===//
881e3e7e5SSchrodinger ZHU Yifan 
981e3e7e5SSchrodinger ZHU Yifan #include "src/__support/HashTable/bitmask.h"
1081e3e7e5SSchrodinger ZHU Yifan 
11*e59582b6SSchrodinger ZHU Yifan #include "src/__support/CPP/bit.h"
125ff3ff33SPetr Hosek #include "src/__support/macros/config.h"
1381e3e7e5SSchrodinger ZHU Yifan #include "src/stdlib/rand.h"
1481e3e7e5SSchrodinger ZHU Yifan #include "test/UnitTest/Test.h"
1581e3e7e5SSchrodinger ZHU Yifan #include <stdint.h>
1681e3e7e5SSchrodinger ZHU Yifan 
175ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL {
1881e3e7e5SSchrodinger ZHU Yifan namespace internal {
1981e3e7e5SSchrodinger ZHU Yifan 
2081e3e7e5SSchrodinger ZHU Yifan struct ByteArray {
2181e3e7e5SSchrodinger ZHU Yifan   alignas(Group) uint8_t data[sizeof(Group) + 1]{};
2281e3e7e5SSchrodinger ZHU Yifan };
2381e3e7e5SSchrodinger ZHU Yifan 
2481e3e7e5SSchrodinger ZHU Yifan TEST(LlvmLibcHashTableBitMaskTest, Match) {
2581e3e7e5SSchrodinger ZHU Yifan   // Any pair of targets have bit differences not only at the lowest bit.
2681e3e7e5SSchrodinger ZHU Yifan   // No False positive.
2781e3e7e5SSchrodinger ZHU Yifan   uint8_t targets[4] = {0x00, 0x11, 0xFF, 0x0F};
2881e3e7e5SSchrodinger ZHU Yifan   size_t count[4] = {0, 0, 0, 0};
2981e3e7e5SSchrodinger ZHU Yifan   size_t appearance[4][sizeof(Group)];
3081e3e7e5SSchrodinger ZHU Yifan   ByteArray array{};
3181e3e7e5SSchrodinger ZHU Yifan 
3281e3e7e5SSchrodinger ZHU Yifan   int data[sizeof(uintptr_t) / sizeof(int)];
3381e3e7e5SSchrodinger ZHU Yifan 
3481e3e7e5SSchrodinger ZHU Yifan   for (int &i : data)
3581e3e7e5SSchrodinger ZHU Yifan     i = rand();
3681e3e7e5SSchrodinger ZHU Yifan 
37*e59582b6SSchrodinger ZHU Yifan   uintptr_t random = cpp::bit_cast<uintptr_t>(data);
38*e59582b6SSchrodinger ZHU Yifan 
3981e3e7e5SSchrodinger ZHU Yifan   for (size_t i = 0; i < sizeof(Group); ++i) {
4081e3e7e5SSchrodinger ZHU Yifan     size_t choice = random % 4;
4181e3e7e5SSchrodinger ZHU Yifan     random /= 4;
4281e3e7e5SSchrodinger ZHU Yifan     array.data[i] = targets[choice];
4381e3e7e5SSchrodinger ZHU Yifan     appearance[choice][count[choice]++] = i;
4481e3e7e5SSchrodinger ZHU Yifan   }
4581e3e7e5SSchrodinger ZHU Yifan 
4681e3e7e5SSchrodinger ZHU Yifan   for (size_t t = 0; t < sizeof(targets); ++t) {
4781e3e7e5SSchrodinger ZHU Yifan     auto bitmask = Group::load(array.data).match_byte(targets[t]);
4881e3e7e5SSchrodinger ZHU Yifan     for (size_t i = 0; i < count[t]; ++i) {
4981e3e7e5SSchrodinger ZHU Yifan       size_t iterated = 0;
5081e3e7e5SSchrodinger ZHU Yifan       for (size_t position : bitmask) {
5181e3e7e5SSchrodinger ZHU Yifan         ASSERT_EQ(appearance[t][iterated], position);
5281e3e7e5SSchrodinger ZHU Yifan         iterated++;
5381e3e7e5SSchrodinger ZHU Yifan       }
5481e3e7e5SSchrodinger ZHU Yifan       ASSERT_EQ(count[t], iterated);
5581e3e7e5SSchrodinger ZHU Yifan     }
5681e3e7e5SSchrodinger ZHU Yifan   }
5781e3e7e5SSchrodinger ZHU Yifan }
5881e3e7e5SSchrodinger ZHU Yifan 
5981e3e7e5SSchrodinger ZHU Yifan TEST(LlvmLibcHashTableBitMaskTest, MaskAvailable) {
6081e3e7e5SSchrodinger ZHU Yifan   uint8_t values[3] = {0x00, 0x0F, 0x80};
6181e3e7e5SSchrodinger ZHU Yifan 
6281e3e7e5SSchrodinger ZHU Yifan   for (size_t i = 0; i < sizeof(Group); ++i) {
6381e3e7e5SSchrodinger ZHU Yifan     ByteArray array{};
6481e3e7e5SSchrodinger ZHU Yifan 
6581e3e7e5SSchrodinger ZHU Yifan     int data[sizeof(uintptr_t) / sizeof(int)];
6681e3e7e5SSchrodinger ZHU Yifan 
6781e3e7e5SSchrodinger ZHU Yifan     for (int &j : data)
6881e3e7e5SSchrodinger ZHU Yifan       j = rand();
6981e3e7e5SSchrodinger ZHU Yifan 
70*e59582b6SSchrodinger ZHU Yifan     uintptr_t random = cpp::bit_cast<uintptr_t>(data);
71*e59582b6SSchrodinger ZHU Yifan 
7281e3e7e5SSchrodinger ZHU Yifan     ASSERT_FALSE(Group::load(array.data).mask_available().any_bit_set());
7381e3e7e5SSchrodinger ZHU Yifan 
7481e3e7e5SSchrodinger ZHU Yifan     array.data[i] = 0x80;
7581e3e7e5SSchrodinger ZHU Yifan     for (size_t j = 0; j < sizeof(Group); ++j) {
7681e3e7e5SSchrodinger ZHU Yifan       if (i == j)
7781e3e7e5SSchrodinger ZHU Yifan         continue;
7881e3e7e5SSchrodinger ZHU Yifan       size_t sample_space = 2 + (j > i);
7981e3e7e5SSchrodinger ZHU Yifan       size_t choice = random % sample_space;
8081e3e7e5SSchrodinger ZHU Yifan       random /= sizeof(values);
8181e3e7e5SSchrodinger ZHU Yifan       array.data[j] = values[choice];
8281e3e7e5SSchrodinger ZHU Yifan     }
8381e3e7e5SSchrodinger ZHU Yifan 
8481e3e7e5SSchrodinger ZHU Yifan     auto mask = Group::load(array.data).mask_available();
8581e3e7e5SSchrodinger ZHU Yifan     ASSERT_TRUE(mask.any_bit_set());
8681e3e7e5SSchrodinger ZHU Yifan     ASSERT_EQ(mask.lowest_set_bit_nonzero(), i);
8781e3e7e5SSchrodinger ZHU Yifan   }
8881e3e7e5SSchrodinger ZHU Yifan }
8981e3e7e5SSchrodinger ZHU Yifan } // namespace internal
905ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL
91