1 // Copyright (c) 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "source/opt/constants.h"
16 
17 #include <gtest/gtest-param-test.h>
18 
19 #include "gtest/gtest.h"
20 #include "source/opt/types.h"
21 
22 namespace spvtools {
23 namespace opt {
24 namespace analysis {
25 namespace {
26 
27 using ConstantTest = ::testing::Test;
28 using ::testing::ValuesIn;
29 
30 template <typename T>
31 struct GetExtendedValueCase {
32   bool is_signed;
33   int width;
34   std::vector<uint32_t> words;
35   T expected_value;
36 };
37 
38 using GetSignExtendedValueCase = GetExtendedValueCase<int64_t>;
39 using GetZeroExtendedValueCase = GetExtendedValueCase<uint64_t>;
40 
41 using GetSignExtendedValueTest =
42     ::testing::TestWithParam<GetSignExtendedValueCase>;
43 using GetZeroExtendedValueTest =
44     ::testing::TestWithParam<GetZeroExtendedValueCase>;
45 
TEST_P(GetSignExtendedValueTest,Case)46 TEST_P(GetSignExtendedValueTest, Case) {
47   Integer type(GetParam().width, GetParam().is_signed);
48   IntConstant value(&type, GetParam().words);
49 
50   EXPECT_EQ(GetParam().expected_value, value.GetSignExtendedValue());
51 }
52 
TEST_P(GetZeroExtendedValueTest,Case)53 TEST_P(GetZeroExtendedValueTest, Case) {
54   Integer type(GetParam().width, GetParam().is_signed);
55   IntConstant value(&type, GetParam().words);
56 
57   EXPECT_EQ(GetParam().expected_value, value.GetZeroExtendedValue());
58 }
59 
60 const uint32_t k32ones = ~uint32_t(0);
61 const uint64_t k64ones = ~uint64_t(0);
62 const int64_t kSBillion = 1000 * 1000 * 1000;
63 const uint64_t kUBillion = 1000 * 1000 * 1000;
64 
65 INSTANTIATE_TEST_SUITE_P(AtMost32Bits, GetSignExtendedValueTest,
66                          ValuesIn(std::vector<GetSignExtendedValueCase>{
67                              // 4 bits
68                              {false, 4, {0}, 0},
69                              {false, 4, {7}, 7},
70                              {false, 4, {15}, 15},
71                              {true, 4, {0}, 0},
72                              {true, 4, {7}, 7},
73                              {true, 4, {0xfffffff8}, -8},
74                              {true, 4, {k32ones}, -1},
75                              // 16 bits
76                              {false, 16, {0}, 0},
77                              {false, 16, {32767}, 32767},
78                              {false, 16, {32768}, 32768},
79                              {false, 16, {65000}, 65000},
80                              {true, 16, {0}, 0},
81                              {true, 16, {32767}, 32767},
82                              {true, 16, {0xfffffff8}, -8},
83                              {true, 16, {k32ones}, -1},
84                              // 32 bits
85                              {false, 32, {0}, 0},
86                              {false, 32, {1000000}, 1000000},
87                              {true, 32, {0xfffffff8}, -8},
88                              {true, 32, {k32ones}, -1},
89                          }));
90 
91 INSTANTIATE_TEST_SUITE_P(AtMost64Bits, GetSignExtendedValueTest,
92                          ValuesIn(std::vector<GetSignExtendedValueCase>{
93                              // 48 bits
94                              {false, 48, {0, 0}, 0},
95                              {false, 48, {5, 0}, 5},
96                              {false, 48, {0xfffffff8, k32ones}, -8},
97                              {false, 48, {k32ones, k32ones}, -1},
98                              {false, 48, {0xdcd65000, 1}, 8 * kSBillion},
99                              {true, 48, {0xfffffff8, k32ones}, -8},
100                              {true, 48, {k32ones, k32ones}, -1},
101                              {true, 48, {0xdcd65000, 1}, 8 * kSBillion},
102 
103                              // 64 bits
104                              {false, 64, {12, 0}, 12},
105                              {false, 64, {0xdcd65000, 1}, 8 * kSBillion},
106                              {false, 48, {0xfffffff8, k32ones}, -8},
107                              {false, 64, {k32ones, k32ones}, -1},
108                              {true, 64, {12, 0}, 12},
109                              {true, 64, {0xdcd65000, 1}, 8 * kSBillion},
110                              {true, 48, {0xfffffff8, k32ones}, -8},
111                              {true, 64, {k32ones, k32ones}, -1},
112                          }));
113 
114 INSTANTIATE_TEST_SUITE_P(AtMost32Bits, GetZeroExtendedValueTest,
115                          ValuesIn(std::vector<GetZeroExtendedValueCase>{
116                              // 4 bits
117                              {false, 4, {0}, 0},
118                              {false, 4, {7}, 7},
119                              {false, 4, {15}, 15},
120                              {true, 4, {0}, 0},
121                              {true, 4, {7}, 7},
122                              {true, 4, {0xfffffff8}, 0xfffffff8},
123                              {true, 4, {k32ones}, k32ones},
124                              // 16 bits
125                              {false, 16, {0}, 0},
126                              {false, 16, {32767}, 32767},
127                              {false, 16, {32768}, 32768},
128                              {false, 16, {65000}, 65000},
129                              {true, 16, {0}, 0},
130                              {true, 16, {32767}, 32767},
131                              {true, 16, {0xfffffff8}, 0xfffffff8},
132                              {true, 16, {k32ones}, k32ones},
133                              // 32 bits
134                              {false, 32, {0}, 0},
135                              {false, 32, {1000000}, 1000000},
136                              {true, 32, {0xfffffff8}, 0xfffffff8},
137                              {true, 32, {k32ones}, k32ones},
138                          }));
139 
140 INSTANTIATE_TEST_SUITE_P(AtMost64Bits, GetZeroExtendedValueTest,
141                          ValuesIn(std::vector<GetZeroExtendedValueCase>{
142                              // 48 bits
143                              {false, 48, {0, 0}, 0},
144                              {false, 48, {5, 0}, 5},
145                              {false, 48, {0xfffffff8, k32ones}, uint64_t(-8)},
146                              {false, 48, {k32ones, k32ones}, uint64_t(-1)},
147                              {false, 48, {0xdcd65000, 1}, 8 * kUBillion},
148                              {true, 48, {0xfffffff8, k32ones}, uint64_t(-8)},
149                              {true, 48, {k32ones, k32ones}, uint64_t(-1)},
150                              {true, 48, {0xdcd65000, 1}, 8 * kUBillion},
151 
152                              // 64 bits
153                              {false, 64, {12, 0}, 12},
154                              {false, 64, {0xdcd65000, 1}, 8 * kUBillion},
155                              {false, 48, {0xfffffff8, k32ones}, uint64_t(-8)},
156                              {false, 64, {k32ones, k32ones}, k64ones},
157                              {true, 64, {12, 0}, 12},
158                              {true, 64, {0xdcd65000, 1}, 8 * kUBillion},
159                              {true, 48, {0xfffffff8, k32ones}, uint64_t(-8)},
160                              {true, 64, {k32ones, k32ones}, k64ones},
161                          }));
162 
163 }  // namespace
164 }  // namespace analysis
165 }  // namespace opt
166 }  // namespace spvtools
167