1*438f7fc0SSiva Chandra Reddy //===-- Benchmark Memory Test ---------------------------------------------===//
2*438f7fc0SSiva Chandra Reddy //
3*438f7fc0SSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*438f7fc0SSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information.
5*438f7fc0SSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*438f7fc0SSiva Chandra Reddy //
7*438f7fc0SSiva Chandra Reddy //===----------------------------------------------------------------------===//
8*438f7fc0SSiva Chandra Reddy 
9*438f7fc0SSiva Chandra Reddy #include "LibcMemoryBenchmark.h"
10*438f7fc0SSiva Chandra Reddy #include "llvm/Support/Alignment.h"
11*438f7fc0SSiva Chandra Reddy #include "gmock/gmock.h"
12*438f7fc0SSiva Chandra Reddy #include "gtest/gtest.h"
13*438f7fc0SSiva Chandra Reddy 
14*438f7fc0SSiva Chandra Reddy using testing::AllOf;
15*438f7fc0SSiva Chandra Reddy using testing::AnyOf;
16*438f7fc0SSiva Chandra Reddy using testing::ElementsAre;
17*438f7fc0SSiva Chandra Reddy using testing::Ge;
18*438f7fc0SSiva Chandra Reddy using testing::Gt;
19*438f7fc0SSiva Chandra Reddy using testing::Le;
20*438f7fc0SSiva Chandra Reddy using testing::Lt;
21*438f7fc0SSiva Chandra Reddy 
22*438f7fc0SSiva Chandra Reddy namespace llvm {
23*438f7fc0SSiva Chandra Reddy namespace libc_benchmarks {
24*438f7fc0SSiva Chandra Reddy namespace {
25*438f7fc0SSiva Chandra Reddy 
26*438f7fc0SSiva Chandra Reddy TEST(AlignedBuffer, IsAligned) {
27*438f7fc0SSiva Chandra Reddy   AlignedBuffer AB(0);
28*438f7fc0SSiva Chandra Reddy   EXPECT_TRUE(isAddrAligned(Align(AlignedBuffer::Alignment), AB.begin()));
29*438f7fc0SSiva Chandra Reddy }
30*438f7fc0SSiva Chandra Reddy 
31*438f7fc0SSiva Chandra Reddy TEST(AlignedBuffer, Empty) {
32*438f7fc0SSiva Chandra Reddy   AlignedBuffer AB(0);
33*438f7fc0SSiva Chandra Reddy   EXPECT_EQ(std::distance(AB.begin(), AB.end()), 0U);
34*438f7fc0SSiva Chandra Reddy }
35*438f7fc0SSiva Chandra Reddy 
36*438f7fc0SSiva Chandra Reddy TEST(OffsetDistribution, AlignToBegin) {
37*438f7fc0SSiva Chandra Reddy   StudyConfiguration Conf;
38*438f7fc0SSiva Chandra Reddy   Conf.BufferSize = 8192;
39*438f7fc0SSiva Chandra Reddy   Conf.AddressAlignment = None;
40*438f7fc0SSiva Chandra Reddy 
41*438f7fc0SSiva Chandra Reddy   OffsetDistribution OD(Conf);
42*438f7fc0SSiva Chandra Reddy   std::default_random_engine Gen;
43*438f7fc0SSiva Chandra Reddy   for (size_t I = 0; I <= 10; ++I)
44*438f7fc0SSiva Chandra Reddy     EXPECT_EQ(OD(Gen), 0U);
45*438f7fc0SSiva Chandra Reddy }
46*438f7fc0SSiva Chandra Reddy 
47*438f7fc0SSiva Chandra Reddy TEST(OffsetDistribution, NoAlignment) {
48*438f7fc0SSiva Chandra Reddy   StudyConfiguration Conf;
49*438f7fc0SSiva Chandra Reddy   Conf.BufferSize = 8192;
50*438f7fc0SSiva Chandra Reddy   Conf.Size.To = 1;
51*438f7fc0SSiva Chandra Reddy 
52*438f7fc0SSiva Chandra Reddy   OffsetDistribution OD(Conf);
53*438f7fc0SSiva Chandra Reddy   std::default_random_engine Gen;
54*438f7fc0SSiva Chandra Reddy   for (size_t I = 0; I <= 10; ++I)
55*438f7fc0SSiva Chandra Reddy     EXPECT_THAT(OD(Gen), AllOf(Ge(0U), Lt(8192U)));
56*438f7fc0SSiva Chandra Reddy }
57*438f7fc0SSiva Chandra Reddy 
58*438f7fc0SSiva Chandra Reddy MATCHER_P(IsDivisibleBy, n, "") {
59*438f7fc0SSiva Chandra Reddy   *result_listener << "where the remainder is " << (arg % n);
60*438f7fc0SSiva Chandra Reddy   return (arg % n) == 0;
61*438f7fc0SSiva Chandra Reddy }
62*438f7fc0SSiva Chandra Reddy 
63*438f7fc0SSiva Chandra Reddy TEST(OffsetDistribution, Aligned) {
64*438f7fc0SSiva Chandra Reddy   StudyConfiguration Conf;
65*438f7fc0SSiva Chandra Reddy   Conf.BufferSize = 8192;
66*438f7fc0SSiva Chandra Reddy   Conf.AddressAlignment = Align(16);
67*438f7fc0SSiva Chandra Reddy   Conf.Size.To = 1;
68*438f7fc0SSiva Chandra Reddy 
69*438f7fc0SSiva Chandra Reddy   OffsetDistribution OD(Conf);
70*438f7fc0SSiva Chandra Reddy   std::default_random_engine Gen;
71*438f7fc0SSiva Chandra Reddy   for (size_t I = 0; I <= 10; ++I)
72*438f7fc0SSiva Chandra Reddy     EXPECT_THAT(OD(Gen), AllOf(Ge(0U), Lt(8192U), IsDivisibleBy(16U)));
73*438f7fc0SSiva Chandra Reddy }
74*438f7fc0SSiva Chandra Reddy 
75*438f7fc0SSiva Chandra Reddy TEST(MismatchOffsetDistribution, EqualBufferDisablesDistribution) {
76*438f7fc0SSiva Chandra Reddy   StudyConfiguration Conf;
77*438f7fc0SSiva Chandra Reddy   Conf.MemcmpMismatchAt = 0; // buffer are equal.
78*438f7fc0SSiva Chandra Reddy 
79*438f7fc0SSiva Chandra Reddy   MismatchOffsetDistribution MOD(Conf);
80*438f7fc0SSiva Chandra Reddy   EXPECT_FALSE(MOD);
81*438f7fc0SSiva Chandra Reddy }
82*438f7fc0SSiva Chandra Reddy 
83*438f7fc0SSiva Chandra Reddy TEST(MismatchOffsetDistribution, DifferentBufferDisablesDistribution) {
84*438f7fc0SSiva Chandra Reddy   StudyConfiguration Conf;
85*438f7fc0SSiva Chandra Reddy   Conf.MemcmpMismatchAt = 1; // buffer are different.
86*438f7fc0SSiva Chandra Reddy 
87*438f7fc0SSiva Chandra Reddy   MismatchOffsetDistribution MOD(Conf);
88*438f7fc0SSiva Chandra Reddy   EXPECT_FALSE(MOD);
89*438f7fc0SSiva Chandra Reddy }
90*438f7fc0SSiva Chandra Reddy 
91*438f7fc0SSiva Chandra Reddy TEST(MismatchOffsetDistribution, MismatchAt2) {
92*438f7fc0SSiva Chandra Reddy   const uint32_t MismatchAt = 2;
93*438f7fc0SSiva Chandra Reddy   const uint32_t ToSize = 4;
94*438f7fc0SSiva Chandra Reddy   StudyConfiguration Conf;
95*438f7fc0SSiva Chandra Reddy   Conf.BufferSize = 16;
96*438f7fc0SSiva Chandra Reddy   Conf.MemcmpMismatchAt = MismatchAt; // buffer are different at position 2.
97*438f7fc0SSiva Chandra Reddy   Conf.Size.To = ToSize;
98*438f7fc0SSiva Chandra Reddy 
99*438f7fc0SSiva Chandra Reddy   MismatchOffsetDistribution MOD(Conf);
100*438f7fc0SSiva Chandra Reddy   EXPECT_TRUE(MOD);
101*438f7fc0SSiva Chandra Reddy   // We test equality up to ToSize (=4) so we need spans of 4 equal bytes spaced
102*438f7fc0SSiva Chandra Reddy   // by one mismatch.
103*438f7fc0SSiva Chandra Reddy   EXPECT_THAT(MOD.getMismatchIndices(), ElementsAre(5, 9, 13));
104*438f7fc0SSiva Chandra Reddy   std::default_random_engine Gen;
105*438f7fc0SSiva Chandra Reddy   for (size_t Iterations = 0; Iterations <= 10; ++Iterations) {
106*438f7fc0SSiva Chandra Reddy     for (size_t Size = Conf.Size.From; Size <= ToSize; ++Size) {
107*438f7fc0SSiva Chandra Reddy       if (Size >= MismatchAt)
108*438f7fc0SSiva Chandra Reddy         EXPECT_THAT(MOD(Gen, Size),
109*438f7fc0SSiva Chandra Reddy                     AnyOf(5 - MismatchAt, 9 - MismatchAt, 13 - MismatchAt));
110*438f7fc0SSiva Chandra Reddy       else
111*438f7fc0SSiva Chandra Reddy         EXPECT_THAT(MOD(Gen, Size),
112*438f7fc0SSiva Chandra Reddy                     AnyOf(5 - Size - 1, 9 - Size - 1, 13 - Size - 1));
113*438f7fc0SSiva Chandra Reddy     }
114*438f7fc0SSiva Chandra Reddy   }
115*438f7fc0SSiva Chandra Reddy }
116*438f7fc0SSiva Chandra Reddy 
117*438f7fc0SSiva Chandra Reddy } // namespace
118*438f7fc0SSiva Chandra Reddy } // namespace libc_benchmarks
119*438f7fc0SSiva Chandra Reddy } // namespace llvm
120