• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- Unittests for control group ---------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "src/__support/HashTable/bitmask.h"
10 
11 #include "src/stdlib/rand.h"
12 #include "test/UnitTest/Test.h"
13 #include <stdint.h>
14 
15 namespace LIBC_NAMESPACE {
16 namespace internal {
17 
18 struct ByteArray {
19   alignas(Group) uint8_t data[sizeof(Group) + 1]{};
20 };
21 
TEST(LlvmLibcHashTableBitMaskTest,Match)22 TEST(LlvmLibcHashTableBitMaskTest, Match) {
23   // Any pair of targets have bit differences not only at the lowest bit.
24   // No False positive.
25   uint8_t targets[4] = {0x00, 0x11, 0xFF, 0x0F};
26   size_t count[4] = {0, 0, 0, 0};
27   size_t appearance[4][sizeof(Group)];
28   ByteArray array{};
29 
30   union {
31     uintptr_t random;
32     int data[sizeof(uintptr_t) / sizeof(int)];
33   };
34 
35   for (int &i : data)
36     i = rand();
37 
38   for (size_t i = 0; i < sizeof(Group); ++i) {
39     size_t choice = random % 4;
40     random /= 4;
41     array.data[i] = targets[choice];
42     appearance[choice][count[choice]++] = i;
43   }
44 
45   for (size_t t = 0; t < sizeof(targets); ++t) {
46     auto bitmask = Group::load(array.data).match_byte(targets[t]);
47     for (size_t i = 0; i < count[t]; ++i) {
48       size_t iterated = 0;
49       for (size_t position : bitmask) {
50         ASSERT_EQ(appearance[t][iterated], position);
51         iterated++;
52       }
53       ASSERT_EQ(count[t], iterated);
54     }
55   }
56 }
57 
TEST(LlvmLibcHashTableBitMaskTest,MaskAvailable)58 TEST(LlvmLibcHashTableBitMaskTest, MaskAvailable) {
59   uint8_t values[3] = {0x00, 0x0F, 0x80};
60 
61   for (size_t i = 0; i < sizeof(Group); ++i) {
62     ByteArray array{};
63 
64     union {
65       uintptr_t random;
66       int data[sizeof(uintptr_t) / sizeof(int)];
67     };
68 
69     for (int &j : data)
70       j = rand();
71 
72     ASSERT_FALSE(Group::load(array.data).mask_available().any_bit_set());
73 
74     array.data[i] = 0x80;
75     for (size_t j = 0; j < sizeof(Group); ++j) {
76       if (i == j)
77         continue;
78       size_t sample_space = 2 + (j > i);
79       size_t choice = random % sample_space;
80       random /= sizeof(values);
81       array.data[j] = values[choice];
82     }
83 
84     auto mask = Group::load(array.data).mask_available();
85     ASSERT_TRUE(mask.any_bit_set());
86     ASSERT_EQ(mask.lowest_set_bit_nonzero(), i);
87   }
88 }
89 } // namespace internal
90 } // namespace LIBC_NAMESPACE
91