• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Test validation of constants.
16 //
17 // This file contains newer tests.  Older tests may be in other files such as
18 // val_id_test.cpp.
19 
20 #include <string>
21 #include <vector>
22 
23 #include "gmock/gmock.h"
24 #include "test/unit_spirv.h"
25 #include "test/val/val_fixtures.h"
26 
27 namespace spvtools {
28 namespace val {
29 namespace {
30 
31 using ::testing::Eq;
32 using ::testing::HasSubstr;
33 using ::testing::ValuesIn;
34 
35 using ValidateConstant = spvtest::ValidateBase<bool>;
36 
37 #define kBasicTypes                             \
38   "%bool = OpTypeBool "                         \
39   "%uint = OpTypeInt 32 0 "                     \
40   "%uint2 = OpTypeVector %uint 2 "              \
41   "%float = OpTypeFloat 32 "                    \
42   "%_ptr_uint = OpTypePointer Workgroup %uint " \
43   "%uint_0 = OpConstantNull %uint "             \
44   "%uint2_0 = OpConstantNull %uint "            \
45   "%float_0 = OpConstantNull %float "           \
46   "%false = OpConstantFalse %bool "             \
47   "%true = OpConstantTrue %bool "               \
48   "%null = OpConstantNull %_ptr_uint "
49 
50 #define kShaderPreamble    \
51   "OpCapability Shader\n"  \
52   "OpCapability Linkage\n" \
53   "OpMemoryModel Logical Simple\n"
54 
55 #define kKernelPreamble      \
56   "OpCapability Kernel\n"    \
57   "OpCapability Linkage\n"   \
58   "OpCapability Addresses\n" \
59   "OpMemoryModel Physical32 OpenCL\n"
60 
61 struct ConstantOpCase {
62   spv_target_env env;
63   std::string assembly;
64   bool expect_success;
65   std::string expect_err;
66 };
67 
68 using ValidateConstantOp = spvtest::ValidateBase<ConstantOpCase>;
69 
TEST_P(ValidateConstantOp,Samples)70 TEST_P(ValidateConstantOp, Samples) {
71   const auto env = GetParam().env;
72   CompileSuccessfully(GetParam().assembly, env);
73   const auto result = ValidateInstructions(env);
74   if (GetParam().expect_success) {
75     EXPECT_EQ(SPV_SUCCESS, result);
76     EXPECT_THAT(getDiagnosticString(), Eq(""));
77   } else {
78     EXPECT_EQ(SPV_ERROR_INVALID_ID, result);
79     EXPECT_THAT(getDiagnosticString(), HasSubstr(GetParam().expect_err));
80   }
81 }
82 
83 #define GOOD_SHADER_10(STR) \
84   { SPV_ENV_UNIVERSAL_1_0, kShaderPreamble kBasicTypes STR, true, "" }
85 #define GOOD_KERNEL_10(STR) \
86   { SPV_ENV_UNIVERSAL_1_0, kKernelPreamble kBasicTypes STR, true, "" }
87 INSTANTIATE_TEST_CASE_P(
88     UniversalInShader, ValidateConstantOp,
89     ValuesIn(std::vector<ConstantOpCase>{
90         // TODO(dneto): Conversions must change width.
91         GOOD_SHADER_10("%v = OpSpecConstantOp %uint SConvert %uint_0"),
92         GOOD_SHADER_10("%v = OpSpecConstantOp %float FConvert %float_0"),
93         GOOD_SHADER_10("%v = OpSpecConstantOp %uint SNegate %uint_0"),
94         GOOD_SHADER_10("%v = OpSpecConstantOp %uint Not %uint_0"),
95         GOOD_SHADER_10("%v = OpSpecConstantOp %uint IAdd %uint_0 %uint_0"),
96         GOOD_SHADER_10("%v = OpSpecConstantOp %uint ISub %uint_0 %uint_0"),
97         GOOD_SHADER_10("%v = OpSpecConstantOp %uint IMul %uint_0 %uint_0"),
98         GOOD_SHADER_10("%v = OpSpecConstantOp %uint UDiv %uint_0 %uint_0"),
99         GOOD_SHADER_10("%v = OpSpecConstantOp %uint SDiv %uint_0 %uint_0"),
100         GOOD_SHADER_10("%v = OpSpecConstantOp %uint UMod %uint_0 %uint_0"),
101         GOOD_SHADER_10("%v = OpSpecConstantOp %uint SRem %uint_0 %uint_0"),
102         GOOD_SHADER_10("%v = OpSpecConstantOp %uint SMod %uint_0 %uint_0"),
103         GOOD_SHADER_10(
104             "%v = OpSpecConstantOp %uint ShiftRightLogical %uint_0 %uint_0"),
105         GOOD_SHADER_10(
106             "%v = OpSpecConstantOp %uint ShiftRightArithmetic %uint_0 %uint_0"),
107         GOOD_SHADER_10(
108             "%v = OpSpecConstantOp %uint ShiftLeftLogical %uint_0 %uint_0"),
109         GOOD_SHADER_10("%v = OpSpecConstantOp %uint BitwiseOr %uint_0 %uint_0"),
110         GOOD_SHADER_10(
111             "%v = OpSpecConstantOp %uint BitwiseXor %uint_0 %uint_0"),
112         GOOD_SHADER_10(
113             "%v = OpSpecConstantOp %uint2 VectorShuffle %uint2_0 %uint2_0 1 3"),
114         GOOD_SHADER_10(
115             "%v = OpSpecConstantOp %uint CompositeExtract %uint2_0 1"),
116         GOOD_SHADER_10(
117             "%v = OpSpecConstantOp %uint2 CompositeInsert %uint_0 %uint2_0 1"),
118         GOOD_SHADER_10("%v = OpSpecConstantOp %bool LogicalOr %true %false"),
119         GOOD_SHADER_10("%v = OpSpecConstantOp %bool LogicalNot %true"),
120         GOOD_SHADER_10("%v = OpSpecConstantOp %bool LogicalAnd %true %false"),
121         GOOD_SHADER_10("%v = OpSpecConstantOp %bool LogicalEqual %true %false"),
122         GOOD_SHADER_10(
123             "%v = OpSpecConstantOp %bool LogicalNotEqual %true %false"),
124         GOOD_SHADER_10(
125             "%v = OpSpecConstantOp %uint Select %true %uint_0 %uint_0"),
126         GOOD_SHADER_10("%v = OpSpecConstantOp %bool IEqual %uint_0 %uint_0"),
127         GOOD_SHADER_10("%v = OpSpecConstantOp %bool INotEqual %uint_0 %uint_0"),
128         GOOD_SHADER_10("%v = OpSpecConstantOp %bool ULessThan %uint_0 %uint_0"),
129         GOOD_SHADER_10("%v = OpSpecConstantOp %bool SLessThan %uint_0 %uint_0"),
130         GOOD_SHADER_10(
131             "%v = OpSpecConstantOp %bool ULessThanEqual %uint_0 %uint_0"),
132         GOOD_SHADER_10(
133             "%v = OpSpecConstantOp %bool SLessThanEqual %uint_0 %uint_0"),
134         GOOD_SHADER_10(
135             "%v = OpSpecConstantOp %bool UGreaterThan %uint_0 %uint_0"),
136         GOOD_SHADER_10(
137             "%v = OpSpecConstantOp %bool UGreaterThanEqual %uint_0 %uint_0"),
138         GOOD_SHADER_10(
139             "%v = OpSpecConstantOp %bool SGreaterThan %uint_0 %uint_0"),
140         GOOD_SHADER_10(
141             "%v = OpSpecConstantOp %bool SGreaterThanEqual %uint_0 %uint_0"),
142     }));
143 
144 INSTANTIATE_TEST_CASE_P(
145     UniversalInKernel, ValidateConstantOp,
146     ValuesIn(std::vector<ConstantOpCase>{
147         // TODO(dneto): Conversions must change width.
148         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SConvert %uint_0"),
149         GOOD_KERNEL_10("%v = OpSpecConstantOp %float FConvert %float_0"),
150         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SNegate %uint_0"),
151         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint Not %uint_0"),
152         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint IAdd %uint_0 %uint_0"),
153         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint ISub %uint_0 %uint_0"),
154         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint IMul %uint_0 %uint_0"),
155         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint UDiv %uint_0 %uint_0"),
156         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SDiv %uint_0 %uint_0"),
157         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint UMod %uint_0 %uint_0"),
158         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SRem %uint_0 %uint_0"),
159         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SMod %uint_0 %uint_0"),
160         GOOD_KERNEL_10(
161             "%v = OpSpecConstantOp %uint ShiftRightLogical %uint_0 %uint_0"),
162         GOOD_KERNEL_10(
163             "%v = OpSpecConstantOp %uint ShiftRightArithmetic %uint_0 %uint_0"),
164         GOOD_KERNEL_10(
165             "%v = OpSpecConstantOp %uint ShiftLeftLogical %uint_0 %uint_0"),
166         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint BitwiseOr %uint_0 %uint_0"),
167         GOOD_KERNEL_10(
168             "%v = OpSpecConstantOp %uint BitwiseXor %uint_0 %uint_0"),
169         GOOD_KERNEL_10(
170             "%v = OpSpecConstantOp %uint2 VectorShuffle %uint2_0 %uint2_0 1 3"),
171         GOOD_KERNEL_10(
172             "%v = OpSpecConstantOp %uint CompositeExtract %uint2_0 1"),
173         GOOD_KERNEL_10(
174             "%v = OpSpecConstantOp %uint2 CompositeInsert %uint_0 %uint2_0 1"),
175         GOOD_KERNEL_10("%v = OpSpecConstantOp %bool LogicalOr %true %false"),
176         GOOD_KERNEL_10("%v = OpSpecConstantOp %bool LogicalNot %true"),
177         GOOD_KERNEL_10("%v = OpSpecConstantOp %bool LogicalAnd %true %false"),
178         GOOD_KERNEL_10("%v = OpSpecConstantOp %bool LogicalEqual %true %false"),
179         GOOD_KERNEL_10(
180             "%v = OpSpecConstantOp %bool LogicalNotEqual %true %false"),
181         GOOD_KERNEL_10(
182             "%v = OpSpecConstantOp %uint Select %true %uint_0 %uint_0"),
183         GOOD_KERNEL_10("%v = OpSpecConstantOp %bool IEqual %uint_0 %uint_0"),
184         GOOD_KERNEL_10("%v = OpSpecConstantOp %bool INotEqual %uint_0 %uint_0"),
185         GOOD_KERNEL_10("%v = OpSpecConstantOp %bool ULessThan %uint_0 %uint_0"),
186         GOOD_KERNEL_10("%v = OpSpecConstantOp %bool SLessThan %uint_0 %uint_0"),
187         GOOD_KERNEL_10(
188             "%v = OpSpecConstantOp %bool ULessThanEqual %uint_0 %uint_0"),
189         GOOD_KERNEL_10(
190             "%v = OpSpecConstantOp %bool SLessThanEqual %uint_0 %uint_0"),
191         GOOD_KERNEL_10(
192             "%v = OpSpecConstantOp %bool UGreaterThan %uint_0 %uint_0"),
193         GOOD_KERNEL_10(
194             "%v = OpSpecConstantOp %bool UGreaterThanEqual %uint_0 %uint_0"),
195         GOOD_KERNEL_10(
196             "%v = OpSpecConstantOp %bool SGreaterThan %uint_0 %uint_0"),
197         GOOD_KERNEL_10(
198             "%v = OpSpecConstantOp %bool SGreaterThanEqual %uint_0 %uint_0"),
199     }));
200 
201 INSTANTIATE_TEST_CASE_P(
202     KernelInKernel, ValidateConstantOp,
203     ValuesIn(std::vector<ConstantOpCase>{
204         // TODO(dneto): Conversions must change width.
205         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint ConvertFToS %float_0"),
206         GOOD_KERNEL_10("%v = OpSpecConstantOp %float ConvertSToF %uint_0"),
207         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint ConvertFToU %float_0"),
208         GOOD_KERNEL_10("%v = OpSpecConstantOp %float ConvertUToF %uint_0"),
209         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint UConvert %uint_0"),
210         GOOD_KERNEL_10(
211             "%v = OpSpecConstantOp %_ptr_uint GenericCastToPtr %null"),
212         GOOD_KERNEL_10(
213             "%v = OpSpecConstantOp %_ptr_uint PtrCastToGeneric %null"),
214         GOOD_KERNEL_10("%v = OpSpecConstantOp %uint Bitcast %uint_0"),
215         GOOD_KERNEL_10("%v = OpSpecConstantOp %float FNegate %float_0"),
216         GOOD_KERNEL_10("%v = OpSpecConstantOp %float FAdd %float_0 %float_0"),
217         GOOD_KERNEL_10("%v = OpSpecConstantOp %float FSub %float_0 %float_0"),
218         GOOD_KERNEL_10("%v = OpSpecConstantOp %float FMul %float_0 %float_0"),
219         GOOD_KERNEL_10("%v = OpSpecConstantOp %float FDiv %float_0 %float_0"),
220         GOOD_KERNEL_10("%v = OpSpecConstantOp %float FRem %float_0 %float_0"),
221         GOOD_KERNEL_10("%v = OpSpecConstantOp %float FMod %float_0 %float_0"),
222         GOOD_KERNEL_10(
223             "%v = OpSpecConstantOp %_ptr_uint AccessChain %null %uint_0"),
224         GOOD_KERNEL_10("%v = OpSpecConstantOp %_ptr_uint InBoundsAccessChain "
225                        "%null %uint_0"),
226         GOOD_KERNEL_10(
227             "%v = OpSpecConstantOp %_ptr_uint PtrAccessChain %null %uint_0"),
228         GOOD_KERNEL_10("%v = OpSpecConstantOp %_ptr_uint "
229                        "InBoundsPtrAccessChain %null %uint_0"),
230     }));
231 
232 #define BAD_SHADER_10(STR, NAME)                                   \
233   {                                                                \
234     SPV_ENV_UNIVERSAL_1_0, kShaderPreamble kBasicTypes STR, false, \
235         "Specialization constant operation " NAME                  \
236         " requires Kernel capability"                              \
237   }
238 INSTANTIATE_TEST_CASE_P(
239     KernelInShader, ValidateConstantOp,
240     ValuesIn(std::vector<ConstantOpCase>{
241         // TODO(dneto): Conversions must change width.
242         BAD_SHADER_10("%v = OpSpecConstantOp %uint ConvertFToS %float_0",
243                       "ConvertFToS"),
244         BAD_SHADER_10("%v = OpSpecConstantOp %float ConvertSToF %uint_0",
245                       "ConvertSToF"),
246         BAD_SHADER_10("%v = OpSpecConstantOp %uint ConvertFToU %float_0",
247                       "ConvertFToU"),
248         BAD_SHADER_10("%v = OpSpecConstantOp %float ConvertUToF %uint_0",
249                       "ConvertUToF"),
250         BAD_SHADER_10("%v = OpSpecConstantOp %_ptr_uint GenericCastToPtr %null",
251                       "GenericCastToPtr"),
252         BAD_SHADER_10("%v = OpSpecConstantOp %_ptr_uint PtrCastToGeneric %null",
253                       "PtrCastToGeneric"),
254         BAD_SHADER_10("%v = OpSpecConstantOp %uint Bitcast %uint_0", "Bitcast"),
255         BAD_SHADER_10("%v = OpSpecConstantOp %float FNegate %float_0",
256                       "FNegate"),
257         BAD_SHADER_10("%v = OpSpecConstantOp %float FAdd %float_0 %float_0",
258                       "FAdd"),
259         BAD_SHADER_10("%v = OpSpecConstantOp %float FSub %float_0 %float_0",
260                       "FSub"),
261         BAD_SHADER_10("%v = OpSpecConstantOp %float FMul %float_0 %float_0",
262                       "FMul"),
263         BAD_SHADER_10("%v = OpSpecConstantOp %float FDiv %float_0 %float_0",
264                       "FDiv"),
265         BAD_SHADER_10("%v = OpSpecConstantOp %float FRem %float_0 %float_0",
266                       "FRem"),
267         BAD_SHADER_10("%v = OpSpecConstantOp %float FMod %float_0 %float_0",
268                       "FMod"),
269         BAD_SHADER_10(
270             "%v = OpSpecConstantOp %_ptr_uint AccessChain %null %uint_0",
271             "AccessChain"),
272         BAD_SHADER_10("%v = OpSpecConstantOp %_ptr_uint InBoundsAccessChain "
273                       "%null %uint_0",
274                       "InBoundsAccessChain"),
275         BAD_SHADER_10(
276             "%v = OpSpecConstantOp %_ptr_uint PtrAccessChain %null %uint_0",
277             "PtrAccessChain"),
278         BAD_SHADER_10("%v = OpSpecConstantOp %_ptr_uint "
279                       "InBoundsPtrAccessChain %null %uint_0",
280                       "InBoundsPtrAccessChain"),
281     }));
282 
283 INSTANTIATE_TEST_CASE_P(
284     UConvertInAMD_gpu_shader_int16, ValidateConstantOp,
285     ValuesIn(std::vector<ConstantOpCase>{
286         // SPV_AMD_gpu_shader_int16 should enable UConvert for OpSpecConstantOp
287         // https://github.com/KhronosGroup/glslang/issues/848
288         {SPV_ENV_UNIVERSAL_1_0,
289          "OpCapability Shader "
290          "OpCapability Linkage ; So we don't need to define a function\n"
291          "OpExtension \"SPV_AMD_gpu_shader_int16\" "
292          "OpMemoryModel Logical Simple " kBasicTypes
293          "%v = OpSpecConstantOp %uint UConvert %uint_0",
294          true, ""},
295     }));
296 
297 }  // namespace
298 }  // namespace val
299 }  // namespace spvtools
300