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