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