Setup dependent external sources
[platform/upstream/VK-GL-CTS.git] / external / spirv-tools / src / test / operand_pattern_test.cpp
1 // Copyright (c) 2015-2016 The Khronos Group Inc.
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 "unit_spirv.h"
16
17 #include "gmock/gmock.h"
18 #include "source/operand.h"
19
20 using ::testing::Eq;
21
22 namespace {
23
24 TEST(OperandPattern, InitiallyEmpty) {
25   spv_operand_pattern_t empty;
26   EXPECT_THAT(empty, Eq(spv_operand_pattern_t{}));
27   EXPECT_EQ(0u, empty.size());
28   EXPECT_TRUE(empty.empty());
29 }
30
31 TEST(OperandPattern, PushFrontsAreOnTheLeft) {
32   spv_operand_pattern_t pattern;
33
34   pattern.push_front(SPV_OPERAND_TYPE_ID);
35   EXPECT_THAT(pattern, Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_ID}));
36   EXPECT_EQ(1u, pattern.size());
37   EXPECT_TRUE(!pattern.empty());
38   EXPECT_EQ(SPV_OPERAND_TYPE_ID, pattern.front());
39
40   pattern.push_front(SPV_OPERAND_TYPE_NONE);
41   EXPECT_THAT(pattern, Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_NONE,
42                                                 SPV_OPERAND_TYPE_ID}));
43   EXPECT_EQ(2u, pattern.size());
44   EXPECT_TRUE(!pattern.empty());
45   EXPECT_EQ(SPV_OPERAND_TYPE_NONE, pattern.front());
46 }
47
48 TEST(OperandPattern, PopFrontsAreOnTheLeft) {
49   spv_operand_pattern_t pattern{SPV_OPERAND_TYPE_LITERAL_INTEGER,
50                                 SPV_OPERAND_TYPE_ID};
51
52   pattern.pop_front();
53   EXPECT_THAT(pattern, Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_ID}));
54
55   pattern.pop_front();
56   EXPECT_THAT(pattern, Eq(spv_operand_pattern_t{}));
57 }
58
59 // A test case for typed mask expansion
60 struct MaskExpansionCase {
61   spv_operand_type_t type;
62   uint32_t mask;
63   spv_operand_pattern_t initial;
64   spv_operand_pattern_t expected;
65 };
66
67 using MaskExpansionTest = ::testing::TestWithParam<MaskExpansionCase>;
68
69 TEST_P(MaskExpansionTest, Sample) {
70   spv_operand_table operandTable = nullptr;
71   ASSERT_EQ(SPV_SUCCESS,
72             spvOperandTableGet(&operandTable, SPV_ENV_UNIVERSAL_1_0));
73
74   spv_operand_pattern_t pattern(GetParam().initial);
75   spvPrependOperandTypesForMask(operandTable, GetParam().type, GetParam().mask,
76                                 &pattern);
77   EXPECT_THAT(pattern, Eq(GetParam().expected));
78 }
79
80 // These macros let us write non-trivial examples without too much text.
81 #define SUFFIX0 SPV_OPERAND_TYPE_NONE, SPV_OPERAND_TYPE_ID
82 #define SUFFIX1                                              \
83   SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE, \
84       SPV_OPERAND_TYPE_STORAGE_CLASS
85 INSTANTIATE_TEST_CASE_P(
86     OperandPattern, MaskExpansionTest,
87     ::testing::ValuesIn(std::vector<MaskExpansionCase>{
88         // No bits means no change.
89         {SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, 0, {SUFFIX0}, {SUFFIX0}},
90         // Unknown bits means no change.
91         {SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS,
92          0xfffffffc,
93          {SUFFIX1},
94          {SUFFIX1}},
95         // Volatile has no operands.
96         {SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS,
97          SpvMemoryAccessVolatileMask,
98          {SUFFIX0},
99          {SUFFIX0}},
100         // Aligned has one literal number operand.
101         {SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS,
102          SpvMemoryAccessAlignedMask,
103          {SUFFIX1},
104          {SPV_OPERAND_TYPE_LITERAL_INTEGER, SUFFIX1}},
105         // Volatile with Aligned still has just one literal number operand.
106         {SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS,
107          SpvMemoryAccessVolatileMask | SpvMemoryAccessAlignedMask,
108          {SUFFIX1},
109          {SPV_OPERAND_TYPE_LITERAL_INTEGER, SUFFIX1}},
110     }), );
111 #undef SUFFIX0
112 #undef SUFFIX1
113
114 // Returns a vector of all operand types that can be used in a pattern.
115 std::vector<spv_operand_type_t> allOperandTypes() {
116   std::vector<spv_operand_type_t> result;
117   for (int i = 0; i < SPV_OPERAND_TYPE_NUM_OPERAND_TYPES; i++) {
118     result.push_back(spv_operand_type_t(i));
119   }
120   return result;
121 }
122
123 using MatchableOperandExpansionTest =
124     ::testing::TestWithParam<spv_operand_type_t>;
125
126 TEST_P(MatchableOperandExpansionTest, MatchableOperandsDontExpand) {
127   const spv_operand_type_t type = GetParam();
128   if (!spvOperandIsVariable(type)) {
129     spv_operand_pattern_t pattern;
130     const bool did_expand = spvExpandOperandSequenceOnce(type, &pattern);
131     EXPECT_FALSE(did_expand);
132     EXPECT_THAT(pattern, Eq(spv_operand_pattern_t{}));
133   }
134 }
135
136 INSTANTIATE_TEST_CASE_P(MatchableOperandExpansion,
137                         MatchableOperandExpansionTest,
138                         ::testing::ValuesIn(allOperandTypes()), );
139
140 using VariableOperandExpansionTest =
141     ::testing::TestWithParam<spv_operand_type_t>;
142
143 TEST_P(VariableOperandExpansionTest, NonMatchableOperandsExpand) {
144   const spv_operand_type_t type = GetParam();
145   if (spvOperandIsVariable(type)) {
146     spv_operand_pattern_t pattern;
147     const bool did_expand = spvExpandOperandSequenceOnce(type, &pattern);
148     EXPECT_TRUE(did_expand);
149     EXPECT_FALSE(pattern.empty());
150     // For the existing rules, the first expansion of a zero-or-more operand
151     // type yields a matchable operand type.  This isn't strictly necessary.
152     EXPECT_FALSE(spvOperandIsVariable(pattern.front()));
153   }
154 }
155
156 INSTANTIATE_TEST_CASE_P(NonMatchableOperandExpansion,
157                         VariableOperandExpansionTest,
158                         ::testing::ValuesIn(allOperandTypes()), );
159
160 TEST(AlternatePatternFollowingImmediate, Empty) {
161   EXPECT_THAT(spvAlternatePatternFollowingImmediate({}),
162               Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_OPTIONAL_CIV}));
163 }
164
165 TEST(AlternatePatternFollowingImmediate, SingleElement) {
166   // Spot-check a random selection of types.
167   EXPECT_THAT(spvAlternatePatternFollowingImmediate(
168                   {SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER}),
169               Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_OPTIONAL_CIV}));
170   EXPECT_THAT(
171       spvAlternatePatternFollowingImmediate({SPV_OPERAND_TYPE_CAPABILITY}),
172       Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_OPTIONAL_CIV}));
173   EXPECT_THAT(
174       spvAlternatePatternFollowingImmediate({SPV_OPERAND_TYPE_LOOP_CONTROL}),
175       Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_OPTIONAL_CIV}));
176   EXPECT_THAT(spvAlternatePatternFollowingImmediate(
177                   {SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER}),
178               Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_OPTIONAL_CIV}));
179   EXPECT_THAT(spvAlternatePatternFollowingImmediate({SPV_OPERAND_TYPE_ID}),
180               Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_OPTIONAL_CIV}));
181 }
182
183 TEST(AlternatePatternFollowingImmediate, SingleResultId) {
184   EXPECT_THAT(
185       spvAlternatePatternFollowingImmediate({SPV_OPERAND_TYPE_RESULT_ID}),
186       Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_RESULT_ID,
187                                SPV_OPERAND_TYPE_OPTIONAL_CIV}));
188 }
189
190 TEST(AlternatePatternFollowingImmediate, MultipleNonResultIds) {
191   EXPECT_THAT(
192       spvAlternatePatternFollowingImmediate(
193           {SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER,
194            SPV_OPERAND_TYPE_CAPABILITY, SPV_OPERAND_TYPE_LOOP_CONTROL,
195            SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID}),
196       Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_OPTIONAL_CIV}));
197 }
198
199 TEST(AlternatePatternFollowingImmediate, ResultIdFront) {
200   EXPECT_THAT(spvAlternatePatternFollowingImmediate(
201                   {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}),
202               Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_RESULT_ID,
203                                        SPV_OPERAND_TYPE_OPTIONAL_CIV}));
204   EXPECT_THAT(spvAlternatePatternFollowingImmediate(
205                   {SPV_OPERAND_TYPE_RESULT_ID,
206                    SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_ID}),
207               Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_RESULT_ID,
208                                        SPV_OPERAND_TYPE_OPTIONAL_CIV}));
209   EXPECT_THAT(spvAlternatePatternFollowingImmediate(
210                   {SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_DIMENSIONALITY,
211                    SPV_OPERAND_TYPE_LINKAGE_TYPE,
212                    SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE,
213                    SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_ID,
214                    SPV_OPERAND_TYPE_VARIABLE_ID}),
215               Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_RESULT_ID,
216                                        SPV_OPERAND_TYPE_OPTIONAL_CIV}));
217 }
218
219 TEST(AlternatePatternFollowingImmediate, ResultIdMiddle) {
220   EXPECT_THAT(spvAlternatePatternFollowingImmediate(
221                   {SPV_OPERAND_TYPE_FP_ROUNDING_MODE,
222                    SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}),
223               Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_OPTIONAL_CIV,
224                                        SPV_OPERAND_TYPE_RESULT_ID,
225                                        SPV_OPERAND_TYPE_OPTIONAL_CIV}));
226   EXPECT_THAT(
227       spvAlternatePatternFollowingImmediate(
228           {SPV_OPERAND_TYPE_DIMENSIONALITY, SPV_OPERAND_TYPE_LINKAGE_TYPE,
229            SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE,
230            SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_FP_ROUNDING_MODE,
231            SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID}),
232       Eq(spv_operand_pattern_t{
233           SPV_OPERAND_TYPE_OPTIONAL_CIV, SPV_OPERAND_TYPE_OPTIONAL_CIV,
234           SPV_OPERAND_TYPE_OPTIONAL_CIV, SPV_OPERAND_TYPE_RESULT_ID,
235           SPV_OPERAND_TYPE_OPTIONAL_CIV}));
236 }
237
238 TEST(AlternatePatternFollowingImmediate, ResultIdBack) {
239   EXPECT_THAT(spvAlternatePatternFollowingImmediate(
240                   {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID}),
241               Eq(spv_operand_pattern_t{SPV_OPERAND_TYPE_OPTIONAL_CIV,
242                                        SPV_OPERAND_TYPE_RESULT_ID,
243                                        SPV_OPERAND_TYPE_OPTIONAL_CIV}));
244   EXPECT_THAT(spvAlternatePatternFollowingImmediate(
245                   {SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_ID,
246                    SPV_OPERAND_TYPE_RESULT_ID}),
247               Eq(spv_operand_pattern_t{
248                   SPV_OPERAND_TYPE_OPTIONAL_CIV, SPV_OPERAND_TYPE_OPTIONAL_CIV,
249                   SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_OPTIONAL_CIV}));
250   EXPECT_THAT(
251       spvAlternatePatternFollowingImmediate(
252           {SPV_OPERAND_TYPE_DIMENSIONALITY, SPV_OPERAND_TYPE_LINKAGE_TYPE,
253            SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE,
254            SPV_OPERAND_TYPE_FP_ROUNDING_MODE, SPV_OPERAND_TYPE_ID,
255            SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_RESULT_ID}),
256       Eq(spv_operand_pattern_t{
257           SPV_OPERAND_TYPE_OPTIONAL_CIV, SPV_OPERAND_TYPE_OPTIONAL_CIV,
258           SPV_OPERAND_TYPE_OPTIONAL_CIV, SPV_OPERAND_TYPE_OPTIONAL_CIV,
259           SPV_OPERAND_TYPE_OPTIONAL_CIV, SPV_OPERAND_TYPE_OPTIONAL_CIV,
260           SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_OPTIONAL_CIV}));
261 }
262
263 }  // anonymous namespace