• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Validation tests for OpVariable storage class
16 
17 #include <sstream>
18 #include <string>
19 #include <tuple>
20 
21 #include "gmock/gmock.h"
22 #include "test/val/val_fixtures.h"
23 
24 namespace spvtools {
25 namespace val {
26 namespace {
27 
28 using ::testing::HasSubstr;
29 using ::testing::Values;
30 using ValidateStorage = spvtest::ValidateBase<std::string>;
31 using ValidateStorageClass =
32     spvtest::ValidateBase<std::tuple<std::string, bool, bool, std::string>>;
33 
TEST_F(ValidateStorage,FunctionStorageInsideFunction)34 TEST_F(ValidateStorage, FunctionStorageInsideFunction) {
35   char str[] = R"(
36           OpCapability Shader
37           OpCapability Linkage
38           OpMemoryModel Logical GLSL450
39 %intt   = OpTypeInt 32 1
40 %voidt  = OpTypeVoid
41 %vfunct = OpTypeFunction %voidt
42 %ptrt   = OpTypePointer Function %intt
43 %func   = OpFunction %voidt None %vfunct
44 %funcl  = OpLabel
45 %var    = OpVariable %ptrt Function
46           OpReturn
47           OpFunctionEnd
48 )";
49 
50   CompileSuccessfully(str);
51   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
52 }
53 
TEST_F(ValidateStorage,FunctionStorageOutsideFunction)54 TEST_F(ValidateStorage, FunctionStorageOutsideFunction) {
55   char str[] = R"(
56           OpCapability Shader
57           OpCapability Linkage
58           OpMemoryModel Logical GLSL450
59 %intt   = OpTypeInt 32 1
60 %voidt  = OpTypeVoid
61 %vfunct = OpTypeFunction %voidt
62 %ptrt   = OpTypePointer Function %intt
63 %var    = OpVariable %ptrt Function
64 %func   = OpFunction %voidt None %vfunct
65 %funcl  = OpLabel
66           OpReturn
67           OpFunctionEnd
68 )";
69 
70   CompileSuccessfully(str);
71   ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
72   EXPECT_THAT(getDiagnosticString(),
73               HasSubstr("Variables can not have a function[7] storage class "
74                         "outside of a function"));
75 }
76 
TEST_F(ValidateStorage,OtherStorageOutsideFunction)77 TEST_F(ValidateStorage, OtherStorageOutsideFunction) {
78   char str[] = R"(
79               OpCapability Shader
80               OpCapability Kernel
81               OpCapability AtomicStorage
82               OpCapability Linkage
83               OpMemoryModel Logical GLSL450
84 %intt       = OpTypeInt 32 0
85 %voidt      = OpTypeVoid
86 %vfunct     = OpTypeFunction %voidt
87 %uniconptrt = OpTypePointer UniformConstant %intt
88 %unicon     = OpVariable %uniconptrt UniformConstant
89 %inputptrt  = OpTypePointer Input %intt
90 %input      = OpVariable %inputptrt Input
91 %unifptrt   = OpTypePointer Uniform %intt
92 %unif       = OpVariable %unifptrt Uniform
93 %outputptrt = OpTypePointer Output %intt
94 %output     = OpVariable %outputptrt Output
95 %wgroupptrt = OpTypePointer Workgroup %intt
96 %wgroup     = OpVariable %wgroupptrt Workgroup
97 %xwgrpptrt  = OpTypePointer CrossWorkgroup %intt
98 %xwgrp      = OpVariable %xwgrpptrt CrossWorkgroup
99 %privptrt   = OpTypePointer Private %intt
100 %priv       = OpVariable %privptrt Private
101 %pushcoptrt = OpTypePointer PushConstant %intt
102 %pushco     = OpVariable %pushcoptrt PushConstant
103 %atomcptrt  = OpTypePointer AtomicCounter %intt
104 %atomct     = OpVariable %atomcptrt AtomicCounter
105 %imageptrt  = OpTypePointer Image %intt
106 %image      = OpVariable %imageptrt Image
107 %func       = OpFunction %voidt None %vfunct
108 %funcl      = OpLabel
109               OpReturn
110               OpFunctionEnd
111 )";
112 
113   CompileSuccessfully(str);
114   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
115 }
116 
117 // clang-format off
TEST_P(ValidateStorage,OtherStorageInsideFunction)118 TEST_P(ValidateStorage, OtherStorageInsideFunction) {
119   std::stringstream ss;
120   ss << R"(
121           OpCapability Shader
122           OpCapability Kernel
123           OpCapability AtomicStorage
124           OpCapability Linkage
125           OpMemoryModel Logical GLSL450
126 %intt   = OpTypeInt 32 0
127 %voidt  = OpTypeVoid
128 %vfunct = OpTypeFunction %voidt
129 %ptrt   = OpTypePointer Function %intt
130 %func   = OpFunction %voidt None %vfunct
131 %funcl  = OpLabel
132 %var    = OpVariable %ptrt )" << GetParam() << R"(
133           OpReturn
134           OpFunctionEnd
135 )";
136 
137   CompileSuccessfully(ss.str());
138   ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
139   EXPECT_THAT(getDiagnosticString(), HasSubstr(
140       "Variables must have a function[7] storage class inside of a function"));
141 }
142 
143 INSTANTIATE_TEST_SUITE_P(MatrixOp, ValidateStorage,
144                         ::testing::Values(
145                              "Input",
146                              "Uniform",
147                              "Output",
148                              "Workgroup",
149                              "CrossWorkgroup",
150                              "Private",
151                              "PushConstant",
152                              "AtomicCounter",
153                              "Image"));
154 // clang-format on
155 
TEST_F(ValidateStorage,GenericVariableOutsideFunction)156 TEST_F(ValidateStorage, GenericVariableOutsideFunction) {
157   const auto str = R"(
158           OpCapability Kernel
159           OpCapability Linkage
160           OpCapability GenericPointer
161           OpMemoryModel Logical OpenCL
162 %intt   = OpTypeInt 32 0
163 %ptrt   = OpTypePointer Function %intt
164 %var    = OpVariable %ptrt Generic
165 )";
166   CompileSuccessfully(str);
167   ASSERT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
168   EXPECT_THAT(getDiagnosticString(),
169               HasSubstr("OpVariable storage class cannot be Generic"));
170 }
171 
TEST_F(ValidateStorage,GenericVariableInsideFunction)172 TEST_F(ValidateStorage, GenericVariableInsideFunction) {
173   const auto str = R"(
174           OpCapability Shader
175           OpCapability Linkage
176           OpCapability GenericPointer
177           OpMemoryModel Logical GLSL450
178 %intt   = OpTypeInt 32 1
179 %voidt  = OpTypeVoid
180 %vfunct = OpTypeFunction %voidt
181 %ptrt   = OpTypePointer Function %intt
182 %func   = OpFunction %voidt None %vfunct
183 %funcl  = OpLabel
184 %var    = OpVariable %ptrt Generic
185           OpReturn
186           OpFunctionEnd
187 )";
188   CompileSuccessfully(str);
189   EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
190   EXPECT_THAT(getDiagnosticString(),
191               HasSubstr("OpVariable storage class cannot be Generic"));
192 }
193 
TEST_F(ValidateStorage,RelaxedLogicalPointerFunctionParam)194 TEST_F(ValidateStorage, RelaxedLogicalPointerFunctionParam) {
195   const auto str = R"(
196           OpCapability Shader
197           OpCapability Linkage
198           OpMemoryModel Logical GLSL450
199 %intt   = OpTypeInt 32 1
200 %voidt  = OpTypeVoid
201 %ptrt   = OpTypePointer Function %intt
202 %vfunct = OpTypeFunction %voidt
203 %vifunct = OpTypeFunction %voidt %ptrt
204 %wgroupptrt = OpTypePointer Workgroup %intt
205 %wgroup = OpVariable %wgroupptrt Workgroup
206 %main   = OpFunction %voidt None %vfunct
207 %mainl  = OpLabel
208 %ret    = OpFunctionCall %voidt %func %wgroup
209           OpReturn
210           OpFunctionEnd
211 %func   = OpFunction %voidt None %vifunct
212 %arg    = OpFunctionParameter %ptrt
213 %funcl  = OpLabel
214           OpReturn
215           OpFunctionEnd
216 )";
217   CompileSuccessfully(str);
218   getValidatorOptions()->before_hlsl_legalization = true;
219   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
220 }
221 
TEST_F(ValidateStorage,RelaxedLogicalPointerFunctionParamBad)222 TEST_F(ValidateStorage, RelaxedLogicalPointerFunctionParamBad) {
223   const auto str = R"(
224           OpCapability Shader
225           OpCapability Linkage
226           OpMemoryModel Logical GLSL450
227 %floatt = OpTypeFloat 32
228 %intt   = OpTypeInt 32 1
229 %voidt  = OpTypeVoid
230 %ptrt   = OpTypePointer Function %intt
231 %vfunct = OpTypeFunction %voidt
232 %vifunct = OpTypeFunction %voidt %ptrt
233 %wgroupptrt = OpTypePointer Workgroup %floatt
234 %wgroup = OpVariable %wgroupptrt Workgroup
235 %main   = OpFunction %voidt None %vfunct
236 %mainl  = OpLabel
237 %ret    = OpFunctionCall %voidt %func %wgroup
238           OpReturn
239           OpFunctionEnd
240 %func   = OpFunction %voidt None %vifunct
241 %arg    = OpFunctionParameter %ptrt
242 %funcl  = OpLabel
243           OpReturn
244           OpFunctionEnd
245 )";
246   CompileSuccessfully(str);
247   getValidatorOptions()->relax_logical_pointer = true;
248   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
249   EXPECT_THAT(getDiagnosticString(),
250               HasSubstr("OpFunctionCall Argument <id> '"));
251 }
252 
253 }  // namespace
254 }  // namespace val
255 }  // namespace spvtools
256