1 | //===- unittests/Support/BlockFrequencyTest.cpp - BlockFrequency tests ----===// |
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 "llvm/Support/BlockFrequency.h" |
10 | #include "llvm/Support/BranchProbability.h" |
11 | #include "llvm/Support/DataTypes.h" |
12 | #include "gtest/gtest.h" |
13 | #include <climits> |
14 | #include <cstdint> |
15 | |
16 | using namespace llvm; |
17 | |
18 | namespace { |
19 | |
20 | TEST(BlockFrequencyTest, OneToZero) { |
21 | BlockFrequency Freq(1); |
22 | BranchProbability Prob(UINT32_MAX / 3, UINT32_MAX); |
23 | Freq *= Prob; |
24 | EXPECT_EQ(Freq.getFrequency(), 0u); |
25 | |
26 | Freq = BlockFrequency(1); |
27 | Freq *= Prob; |
28 | EXPECT_EQ(Freq.getFrequency(), 0u); |
29 | } |
30 | |
31 | TEST(BlockFrequencyTest, OneToOne) { |
32 | BlockFrequency Freq(1); |
33 | BranchProbability Prob(UINT32_MAX, UINT32_MAX); |
34 | Freq *= Prob; |
35 | EXPECT_EQ(Freq.getFrequency(), 1u); |
36 | |
37 | Freq = BlockFrequency(1); |
38 | Freq *= Prob; |
39 | EXPECT_EQ(Freq.getFrequency(), 1u); |
40 | } |
41 | |
42 | TEST(BlockFrequencyTest, ThreeToOne) { |
43 | BlockFrequency Freq(3); |
44 | BranchProbability Prob(3000000, 9000000); |
45 | Freq *= Prob; |
46 | EXPECT_EQ(Freq.getFrequency(), 1u); |
47 | |
48 | Freq = BlockFrequency(3); |
49 | Freq *= Prob; |
50 | EXPECT_EQ(Freq.getFrequency(), 1u); |
51 | } |
52 | |
53 | TEST(BlockFrequencyTest, MaxToHalfMax) { |
54 | BlockFrequency Freq(UINT64_MAX); |
55 | BranchProbability Prob(UINT32_MAX / 2, UINT32_MAX); |
56 | Freq *= Prob; |
57 | EXPECT_EQ(Freq.getFrequency(), 9223372036854775807ULL); |
58 | |
59 | Freq = BlockFrequency(UINT64_MAX); |
60 | Freq *= Prob; |
61 | EXPECT_EQ(Freq.getFrequency(), 9223372036854775807ULL); |
62 | } |
63 | |
64 | TEST(BlockFrequencyTest, BigToBig) { |
65 | const uint64_t Big = 387246523487234346LL; |
66 | const uint32_t P = 123456789; |
67 | BlockFrequency Freq(Big); |
68 | BranchProbability Prob(P, P); |
69 | Freq *= Prob; |
70 | EXPECT_EQ(Freq.getFrequency(), Big); |
71 | |
72 | Freq = BlockFrequency(Big); |
73 | Freq *= Prob; |
74 | EXPECT_EQ(Freq.getFrequency(), Big); |
75 | } |
76 | |
77 | TEST(BlockFrequencyTest, MaxToMax) { |
78 | BlockFrequency Freq(UINT64_MAX); |
79 | BranchProbability Prob(UINT32_MAX, UINT32_MAX); |
80 | Freq *= Prob; |
81 | EXPECT_EQ(Freq.getFrequency(), UINT64_MAX); |
82 | |
83 | // This additionally makes sure if we have a value equal to our saturating |
84 | // value, we do not signal saturation if the result equals said value, but |
85 | // saturating does not occur. |
86 | Freq = BlockFrequency(UINT64_MAX); |
87 | Freq *= Prob; |
88 | EXPECT_EQ(Freq.getFrequency(), UINT64_MAX); |
89 | } |
90 | |
91 | TEST(BlockFrequencyTest, Subtract) { |
92 | BlockFrequency Freq1(0), Freq2(1); |
93 | EXPECT_EQ((Freq1 - Freq2).getFrequency(), 0u); |
94 | EXPECT_EQ((Freq2 - Freq1).getFrequency(), 1u); |
95 | } |
96 | |
97 | TEST(BlockFrequency, Divide) { |
98 | BlockFrequency Freq(0x3333333333333333ULL); |
99 | Freq /= BranchProbability(1, 2); |
100 | EXPECT_EQ(Freq.getFrequency(), 0x6666666666666666ULL); |
101 | } |
102 | |
103 | TEST(BlockFrequencyTest, Saturate) { |
104 | BlockFrequency Freq(0x3333333333333333ULL); |
105 | Freq /= BranchProbability(100, 300); |
106 | EXPECT_EQ(Freq.getFrequency(), 0x9999999866666668ULL); |
107 | Freq /= BranchProbability(1, 2); |
108 | EXPECT_EQ(Freq.getFrequency(), UINT64_MAX); |
109 | |
110 | Freq = BlockFrequency(UINT64_C(0x1000000000000000)); |
111 | Freq /= BranchProbability(10000, 170000); |
112 | EXPECT_EQ(Freq.getFrequency(), UINT64_MAX); |
113 | |
114 | // Try to cheat the multiplication overflow check. |
115 | Freq = BlockFrequency(UINT64_C(0x00000001f0000001)); |
116 | Freq /= BranchProbability(1000, 0xf000000f); |
117 | EXPECT_EQ(33527736066704712ULL, Freq.getFrequency()); |
118 | } |
119 | |
120 | TEST(BlockFrequencyTest, SaturatingRightShift) { |
121 | BlockFrequency Freq(0x10080ULL); |
122 | Freq >>= 2; |
123 | EXPECT_EQ(Freq.getFrequency(), 0x4020ULL); |
124 | Freq >>= 20; |
125 | EXPECT_EQ(Freq.getFrequency(), 0x1ULL); |
126 | } |
127 | |
128 | } |
129 | |