1 // Copyright (c) 2017 Google 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 <string>
16 #include <vector>
17
18 #include "pass_utils.h"
19 #include "test/opt/assembly_builder.h"
20 #include "test/opt/pass_fixture.h"
21
22 namespace spvtools {
23 namespace opt {
24 namespace {
25
26 using ReplaceInvalidOpcodeTest = PassTest<::testing::Test>;
27
TEST_F(ReplaceInvalidOpcodeTest,ReplaceInstruction)28 TEST_F(ReplaceInvalidOpcodeTest, ReplaceInstruction) {
29 const std::string text = R"(
30 ; CHECK: [[special_const:%\w+]] = OpConstant %float -6.2598534e+18
31 ; CHECK: [[constant:%\w+]] = OpConstantComposite %v4float [[special_const]] [[special_const]] [[special_const]] [[special_const]]
32 ; CHECK-NOT: OpImageSampleImplicitLod
33 ; CHECK: OpStore [[:%\w+]] [[constant]]
34 OpCapability Shader
35 %1 = OpExtInstImport "GLSL.std.450"
36 OpMemoryModel Logical GLSL450
37 OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
38 OpSource GLSL 400
39 OpSourceExtension "GL_ARB_separate_shader_objects"
40 OpSourceExtension "GL_ARB_shading_language_420pack"
41 OpName %main "main"
42 OpDecorate %3 Location 0
43 OpDecorate %gl_VertexIndex BuiltIn VertexIndex
44 OpMemberDecorate %_struct_6 0 BuiltIn Position
45 OpDecorate %_struct_6 Block
46 %void = OpTypeVoid
47 %8 = OpTypeFunction %void
48 %float = OpTypeFloat 32
49 %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
50 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
51 %12 = OpTypeSampler
52 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
53 %14 = OpTypeSampledImage %10
54 %v4float = OpTypeVector %float 4
55 %v2float = OpTypeVector %float 2
56 %_ptr_Output_v4float = OpTypePointer Output %v4float
57 %3 = OpVariable %_ptr_Output_v4float Output
58 %int = OpTypeInt 32 1
59 %_ptr_Input_int = OpTypePointer Input %int
60 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
61 %_struct_6 = OpTypeStruct %v4float
62 %_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
63 %5 = OpVariable %_ptr_Output__struct_6 Output
64 %int_0 = OpConstant %int 0
65 %float_0 = OpConstant %float 0
66 %23 = OpConstantComposite %v2float %float_0 %float_0
67 %24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
68 %25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
69 %main = OpFunction %void None %8
70 %26 = OpLabel
71 %27 = OpLoad %12 %25
72 %28 = OpLoad %10 %24
73 %29 = OpSampledImage %14 %28 %27
74 %30 = OpImageSampleImplicitLod %v4float %29 %23
75 %31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
76 OpStore %31 %30
77 OpReturn
78 OpFunctionEnd)";
79
80 SinglePassRunAndMatch<ReplaceInvalidOpcodePass>(text, false);
81 }
82
TEST_F(ReplaceInvalidOpcodeTest,ReplaceInstructionInNonEntryPoint)83 TEST_F(ReplaceInvalidOpcodeTest, ReplaceInstructionInNonEntryPoint) {
84 const std::string text = R"(
85 ; CHECK: [[special_const:%\w+]] = OpConstant %float -6.2598534e+18
86 ; CHECK: [[constant:%\w+]] = OpConstantComposite %v4float [[special_const]] [[special_const]] [[special_const]] [[special_const]]
87 ; CHECK-NOT: OpImageSampleImplicitLod
88 ; CHECK: OpStore [[:%\w+]] [[constant]]
89 OpCapability Shader
90 %1 = OpExtInstImport "GLSL.std.450"
91 OpMemoryModel Logical GLSL450
92 OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
93 OpSource GLSL 400
94 OpSourceExtension "GL_ARB_separate_shader_objects"
95 OpSourceExtension "GL_ARB_shading_language_420pack"
96 OpName %main "main"
97 OpDecorate %3 Location 0
98 OpDecorate %gl_VertexIndex BuiltIn VertexIndex
99 OpMemberDecorate %_struct_6 0 BuiltIn Position
100 OpDecorate %_struct_6 Block
101 %void = OpTypeVoid
102 %8 = OpTypeFunction %void
103 %float = OpTypeFloat 32
104 %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
105 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
106 %12 = OpTypeSampler
107 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
108 %14 = OpTypeSampledImage %10
109 %v4float = OpTypeVector %float 4
110 %v2float = OpTypeVector %float 2
111 %_ptr_Output_v4float = OpTypePointer Output %v4float
112 %3 = OpVariable %_ptr_Output_v4float Output
113 %int = OpTypeInt 32 1
114 %_ptr_Input_int = OpTypePointer Input %int
115 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
116 %_struct_6 = OpTypeStruct %v4float
117 %_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
118 %5 = OpVariable %_ptr_Output__struct_6 Output
119 %int_0 = OpConstant %int 0
120 %float_0 = OpConstant %float 0
121 %23 = OpConstantComposite %v2float %float_0 %float_0
122 %24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
123 %25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
124 %main = OpFunction %void None %8
125 %26 = OpLabel
126 %27 = OpFunctionCall %void %28
127 OpReturn
128 OpFunctionEnd
129 %28 = OpFunction %void None %8
130 %29 = OpLabel
131 %30 = OpLoad %12 %25
132 %31 = OpLoad %10 %24
133 %32 = OpSampledImage %14 %31 %30
134 %33 = OpImageSampleImplicitLod %v4float %32 %23
135 %34 = OpAccessChain %_ptr_Output_v4float %5 %int_0
136 OpStore %34 %33
137 OpReturn
138 OpFunctionEnd)";
139
140 SinglePassRunAndMatch<ReplaceInvalidOpcodePass>(text, false);
141 }
142
TEST_F(ReplaceInvalidOpcodeTest,ReplaceInstructionMultipleEntryPoints)143 TEST_F(ReplaceInvalidOpcodeTest, ReplaceInstructionMultipleEntryPoints) {
144 const std::string text = R"(
145 ; CHECK: [[special_const:%\w+]] = OpConstant %float -6.2598534e+18
146 ; CHECK: [[constant:%\w+]] = OpConstantComposite %v4float [[special_const]] [[special_const]] [[special_const]] [[special_const]]
147 ; CHECK-NOT: OpImageSampleImplicitLod
148 ; CHECK: OpStore [[:%\w+]] [[constant]]
149 ; CHECK-NOT: OpImageSampleImplicitLod
150 ; CHECK: OpStore [[:%\w+]] [[constant]]
151 OpCapability Shader
152 %1 = OpExtInstImport "GLSL.std.450"
153 OpMemoryModel Logical GLSL450
154 OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
155 OpEntryPoint Vertex %main2 "main2" %3 %gl_VertexIndex %5
156 OpSource GLSL 400
157 OpSourceExtension "GL_ARB_separate_shader_objects"
158 OpSourceExtension "GL_ARB_shading_language_420pack"
159 OpName %main "main"
160 OpName %main2 "main2"
161 OpDecorate %3 Location 0
162 OpDecorate %gl_VertexIndex BuiltIn VertexIndex
163 OpMemberDecorate %_struct_6 0 BuiltIn Position
164 OpDecorate %_struct_6 Block
165 %void = OpTypeVoid
166 %8 = OpTypeFunction %void
167 %float = OpTypeFloat 32
168 %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
169 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
170 %12 = OpTypeSampler
171 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
172 %14 = OpTypeSampledImage %10
173 %v4float = OpTypeVector %float 4
174 %v2float = OpTypeVector %float 2
175 %_ptr_Output_v4float = OpTypePointer Output %v4float
176 %3 = OpVariable %_ptr_Output_v4float Output
177 %int = OpTypeInt 32 1
178 %_ptr_Input_int = OpTypePointer Input %int
179 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
180 %_struct_6 = OpTypeStruct %v4float
181 %_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
182 %5 = OpVariable %_ptr_Output__struct_6 Output
183 %int_0 = OpConstant %int 0
184 %float_0 = OpConstant %float 0
185 %23 = OpConstantComposite %v2float %float_0 %float_0
186 %24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
187 %25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
188 %main = OpFunction %void None %8
189 %26 = OpLabel
190 %27 = OpLoad %12 %25
191 %28 = OpLoad %10 %24
192 %29 = OpSampledImage %14 %28 %27
193 %30 = OpImageSampleImplicitLod %v4float %29 %23
194 %31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
195 OpStore %31 %30
196 OpReturn
197 OpFunctionEnd
198 %main2 = OpFunction %void None %8
199 %46 = OpLabel
200 %47 = OpLoad %12 %25
201 %48 = OpLoad %10 %24
202 %49 = OpSampledImage %14 %48 %47
203 %50 = OpImageSampleImplicitLod %v4float %49 %23
204 %51 = OpAccessChain %_ptr_Output_v4float %5 %int_0
205 OpStore %51 %50
206 OpReturn
207 OpFunctionEnd)";
208
209 SinglePassRunAndMatch<ReplaceInvalidOpcodePass>(text, false);
210 }
TEST_F(ReplaceInvalidOpcodeTest,DontReplaceInstruction)211 TEST_F(ReplaceInvalidOpcodeTest, DontReplaceInstruction) {
212 const std::string text = R"(
213 OpCapability Shader
214 %1 = OpExtInstImport "GLSL.std.450"
215 OpMemoryModel Logical GLSL450
216 OpEntryPoint Fragment %main "main" %3 %gl_VertexIndex %5
217 OpSource GLSL 400
218 OpSourceExtension "GL_ARB_separate_shader_objects"
219 OpSourceExtension "GL_ARB_shading_language_420pack"
220 OpName %main "main"
221 OpDecorate %3 Location 0
222 OpDecorate %gl_VertexIndex BuiltIn VertexIndex
223 OpMemberDecorate %_struct_6 0 BuiltIn Position
224 OpDecorate %_struct_6 Block
225 %void = OpTypeVoid
226 %8 = OpTypeFunction %void
227 %float = OpTypeFloat 32
228 %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
229 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
230 %12 = OpTypeSampler
231 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
232 %14 = OpTypeSampledImage %10
233 %v4float = OpTypeVector %float 4
234 %v2float = OpTypeVector %float 2
235 %_ptr_Output_v4float = OpTypePointer Output %v4float
236 %3 = OpVariable %_ptr_Output_v4float Output
237 %int = OpTypeInt 32 1
238 %_ptr_Input_int = OpTypePointer Input %int
239 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
240 %_struct_6 = OpTypeStruct %v4float
241 %_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
242 %5 = OpVariable %_ptr_Output__struct_6 Output
243 %int_0 = OpConstant %int 0
244 %float_0 = OpConstant %float 0
245 %23 = OpConstantComposite %v2float %float_0 %float_0
246 %24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
247 %25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
248 %main = OpFunction %void None %8
249 %26 = OpLabel
250 %27 = OpLoad %12 %25
251 %28 = OpLoad %10 %24
252 %29 = OpSampledImage %14 %28 %27
253 %30 = OpImageSampleImplicitLod %v4float %29 %23
254 %31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
255 OpStore %31 %30
256 OpReturn
257 OpFunctionEnd)";
258
259 auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
260 text, /* skip_nop = */ true, /* do_validation = */ false);
261 EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
262 }
263
TEST_F(ReplaceInvalidOpcodeTest,MultipleEntryPointsDifferentStage)264 TEST_F(ReplaceInvalidOpcodeTest, MultipleEntryPointsDifferentStage) {
265 const std::string text = R"(
266 OpCapability Shader
267 %1 = OpExtInstImport "GLSL.std.450"
268 OpMemoryModel Logical GLSL450
269 OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
270 OpEntryPoint Fragment %main2 "main2" %3 %gl_VertexIndex %5
271 OpSource GLSL 400
272 OpSourceExtension "GL_ARB_separate_shader_objects"
273 OpSourceExtension "GL_ARB_shading_language_420pack"
274 OpName %main "main"
275 OpName %main2 "main2"
276 OpDecorate %3 Location 0
277 OpDecorate %gl_VertexIndex BuiltIn VertexIndex
278 OpMemberDecorate %_struct_6 0 BuiltIn Position
279 OpDecorate %_struct_6 Block
280 %void = OpTypeVoid
281 %8 = OpTypeFunction %void
282 %float = OpTypeFloat 32
283 %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
284 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
285 %12 = OpTypeSampler
286 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
287 %14 = OpTypeSampledImage %10
288 %v4float = OpTypeVector %float 4
289 %v2float = OpTypeVector %float 2
290 %_ptr_Output_v4float = OpTypePointer Output %v4float
291 %3 = OpVariable %_ptr_Output_v4float Output
292 %int = OpTypeInt 32 1
293 %_ptr_Input_int = OpTypePointer Input %int
294 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
295 %_struct_6 = OpTypeStruct %v4float
296 %_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
297 %5 = OpVariable %_ptr_Output__struct_6 Output
298 %int_0 = OpConstant %int 0
299 %float_0 = OpConstant %float 0
300 %23 = OpConstantComposite %v2float %float_0 %float_0
301 %24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
302 %25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
303 %main = OpFunction %void None %8
304 %26 = OpLabel
305 %27 = OpLoad %12 %25
306 %28 = OpLoad %10 %24
307 %29 = OpSampledImage %14 %28 %27
308 %30 = OpImageSampleImplicitLod %v4float %29 %23
309 %31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
310 OpStore %31 %30
311 OpReturn
312 OpFunctionEnd
313 %main2 = OpFunction %void None %8
314 %46 = OpLabel
315 %47 = OpLoad %12 %25
316 %48 = OpLoad %10 %24
317 %49 = OpSampledImage %14 %48 %47
318 %50 = OpImageSampleImplicitLod %v4float %49 %23
319 %51 = OpAccessChain %_ptr_Output_v4float %5 %int_0
320 OpStore %51 %50
321 OpReturn
322 OpFunctionEnd)";
323
324 auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
325 text, /* skip_nop = */ true, /* do_validation = */ false);
326 EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
327 }
328
TEST_F(ReplaceInvalidOpcodeTest,DontReplaceLinkage)329 TEST_F(ReplaceInvalidOpcodeTest, DontReplaceLinkage) {
330 const std::string text = R"(
331 OpCapability Shader
332 OpCapability Linkage
333 %1 = OpExtInstImport "GLSL.std.450"
334 OpMemoryModel Logical GLSL450
335 OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
336 OpSource GLSL 400
337 OpSourceExtension "GL_ARB_separate_shader_objects"
338 OpSourceExtension "GL_ARB_shading_language_420pack"
339 OpName %main "main"
340 OpDecorate %3 Location 0
341 OpDecorate %gl_VertexIndex BuiltIn VertexIndex
342 OpMemberDecorate %_struct_6 0 BuiltIn Position
343 OpDecorate %_struct_6 Block
344 %void = OpTypeVoid
345 %8 = OpTypeFunction %void
346 %float = OpTypeFloat 32
347 %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
348 %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
349 %12 = OpTypeSampler
350 %_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
351 %14 = OpTypeSampledImage %10
352 %v4float = OpTypeVector %float 4
353 %v2float = OpTypeVector %float 2
354 %_ptr_Output_v4float = OpTypePointer Output %v4float
355 %3 = OpVariable %_ptr_Output_v4float Output
356 %int = OpTypeInt 32 1
357 %_ptr_Input_int = OpTypePointer Input %int
358 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
359 %_struct_6 = OpTypeStruct %v4float
360 %_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
361 %5 = OpVariable %_ptr_Output__struct_6 Output
362 %int_0 = OpConstant %int 0
363 %float_0 = OpConstant %float 0
364 %23 = OpConstantComposite %v2float %float_0 %float_0
365 %24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
366 %25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
367 %main = OpFunction %void None %8
368 %26 = OpLabel
369 %27 = OpLoad %12 %25
370 %28 = OpLoad %10 %24
371 %29 = OpSampledImage %14 %28 %27
372 %30 = OpImageSampleImplicitLod %v4float %29 %23
373 %31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
374 OpStore %31 %30
375 OpReturn
376 OpFunctionEnd)";
377
378 auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
379 text, /* skip_nop = */ true, /* do_validation = */ false);
380 EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
381 }
382
TEST_F(ReplaceInvalidOpcodeTest,BarrierDontReplace)383 TEST_F(ReplaceInvalidOpcodeTest, BarrierDontReplace) {
384 const std::string text = R"(
385 OpCapability Shader
386 %1 = OpExtInstImport "GLSL.std.450"
387 OpMemoryModel Logical GLSL450
388 OpEntryPoint GLCompute %main "main"
389 OpExecutionMode %main LocalSize 1 1 1
390 OpSource GLSL 450
391 OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
392 OpSourceExtension "GL_GOOGLE_include_directive"
393 OpName %main "main"
394 %void = OpTypeVoid
395 %3 = OpTypeFunction %void
396 %uint = OpTypeInt 32 0
397 %uint_2 = OpConstant %uint 2
398 %uint_264 = OpConstant %uint 264
399 %main = OpFunction %void None %3
400 %5 = OpLabel
401 OpControlBarrier %uint_2 %uint_2 %uint_264
402 OpReturn
403 OpFunctionEnd)";
404
405 SetTargetEnv(SPV_ENV_UNIVERSAL_1_2);
406 auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
407 text, /* skip_nop = */ true, /* do_validation = */ false);
408 EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
409 }
410
TEST_F(ReplaceInvalidOpcodeTest,BarrierReplace)411 TEST_F(ReplaceInvalidOpcodeTest, BarrierReplace) {
412 const std::string text = R"(
413 ; CHECK-NOT: OpControlBarrier
414 OpCapability Shader
415 %1 = OpExtInstImport "GLSL.std.450"
416 OpMemoryModel Logical GLSL450
417 OpEntryPoint Vertex %main "main"
418 OpExecutionMode %main LocalSize 1 1 1
419 OpSource GLSL 450
420 OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
421 OpSourceExtension "GL_GOOGLE_include_directive"
422 OpName %main "main"
423 %void = OpTypeVoid
424 %3 = OpTypeFunction %void
425 %uint = OpTypeInt 32 0
426 %uint_2 = OpConstant %uint 2
427 %uint_264 = OpConstant %uint 264
428 %main = OpFunction %void None %3
429 %5 = OpLabel
430 OpControlBarrier %uint_2 %uint_2 %uint_264
431 OpReturn
432 OpFunctionEnd)";
433
434 SetTargetEnv(SPV_ENV_UNIVERSAL_1_2);
435 SinglePassRunAndMatch<ReplaceInvalidOpcodePass>(text, false);
436 }
437
438 // Since version 1.3 OpControlBarriers are allowed is more shaders.
439 // https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpControlBarrier
TEST_F(ReplaceInvalidOpcodeTest,BarrierDontReplaceV13)440 TEST_F(ReplaceInvalidOpcodeTest, BarrierDontReplaceV13) {
441 const std::string text = R"(
442 OpCapability Shader
443 %1 = OpExtInstImport "GLSL.std.450"
444 OpMemoryModel Logical GLSL450
445 OpEntryPoint Vertex %main "main"
446 OpExecutionMode %main LocalSize 1 1 1
447 OpSource GLSL 450
448 OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
449 OpSourceExtension "GL_GOOGLE_include_directive"
450 OpName %main "main"
451 %void = OpTypeVoid
452 %3 = OpTypeFunction %void
453 %uint = OpTypeInt 32 0
454 %uint_2 = OpConstant %uint 2
455 %uint_264 = OpConstant %uint 264
456 %main = OpFunction %void None %3
457 %5 = OpLabel
458 OpControlBarrier %uint_2 %uint_2 %uint_264
459 OpReturn
460 OpFunctionEnd)";
461
462 SetTargetEnv(SPV_ENV_UNIVERSAL_1_3);
463 auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
464 text, /* skip_nop = */ true, /* do_validation = */ false);
465 EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
466 }
467
TEST_F(ReplaceInvalidOpcodeTest,MessageTest)468 TEST_F(ReplaceInvalidOpcodeTest, MessageTest) {
469 const std::string text = R"(
470 OpCapability Shader
471 %1 = OpExtInstImport "GLSL.std.450"
472 OpMemoryModel Logical GLSL450
473 OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
474 OpSource GLSL 400
475 %6 = OpString "test.hlsl"
476 OpSourceExtension "GL_ARB_separate_shader_objects"
477 OpSourceExtension "GL_ARB_shading_language_420pack"
478 OpName %main "main"
479 OpDecorate %3 Location 0
480 OpDecorate %gl_VertexIndex BuiltIn VertexIndex
481 OpMemberDecorate %_struct_7 0 BuiltIn Position
482 OpDecorate %_struct_7 Block
483 %void = OpTypeVoid
484 %9 = OpTypeFunction %void
485 %float = OpTypeFloat 32
486 %11 = OpTypeImage %float 2D 0 0 0 1 Unknown
487 %_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
488 %13 = OpTypeSampler
489 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
490 %15 = OpTypeSampledImage %11
491 %v4float = OpTypeVector %float 4
492 %v2float = OpTypeVector %float 2
493 %_ptr_Output_v4float = OpTypePointer Output %v4float
494 %3 = OpVariable %_ptr_Output_v4float Output
495 %int = OpTypeInt 32 1
496 %_ptr_Input_int = OpTypePointer Input %int
497 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
498 %_struct_7 = OpTypeStruct %v4float
499 %_ptr_Output__struct_7 = OpTypePointer Output %_struct_7
500 %5 = OpVariable %_ptr_Output__struct_7 Output
501 %int_0 = OpConstant %int 0
502 %float_0 = OpConstant %float 0
503 %24 = OpConstantComposite %v2float %float_0 %float_0
504 %25 = OpVariable %_ptr_UniformConstant_11 UniformConstant
505 %26 = OpVariable %_ptr_UniformConstant_13 UniformConstant
506 %main = OpFunction %void None %9
507 %27 = OpLabel
508 OpLine %6 2 4
509 %28 = OpLoad %13 %26
510 %29 = OpLoad %11 %25
511 %30 = OpSampledImage %15 %29 %28
512 %31 = OpImageSampleImplicitLod %v4float %30 %24
513 %32 = OpAccessChain %_ptr_Output_v4float %5 %int_0
514 OpStore %32 %31
515 OpReturn
516 OpFunctionEnd)";
517
518 std::vector<Message> messages = {
519 {SPV_MSG_WARNING, "test.hlsl", 2, 4,
520 "Removing ImageSampleImplicitLod instruction because of incompatible "
521 "execution model."}};
522 SetMessageConsumer(GetTestMessageConsumer(messages));
523 auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
524 text, /* skip_nop = */ true, /* do_validation = */ false);
525 EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
526 }
527
TEST_F(ReplaceInvalidOpcodeTest,MultipleMessageTest)528 TEST_F(ReplaceInvalidOpcodeTest, MultipleMessageTest) {
529 const std::string text = R"(
530 OpCapability Shader
531 %1 = OpExtInstImport "GLSL.std.450"
532 OpMemoryModel Logical GLSL450
533 OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
534 OpSource GLSL 400
535 %6 = OpString "test.hlsl"
536 OpSourceExtension "GL_ARB_separate_shader_objects"
537 OpSourceExtension "GL_ARB_shading_language_420pack"
538 OpName %main "main"
539 OpDecorate %3 Location 0
540 OpDecorate %gl_VertexIndex BuiltIn VertexIndex
541 OpMemberDecorate %_struct_7 0 BuiltIn Position
542 OpDecorate %_struct_7 Block
543 %void = OpTypeVoid
544 %9 = OpTypeFunction %void
545 %float = OpTypeFloat 32
546 %11 = OpTypeImage %float 2D 0 0 0 1 Unknown
547 %_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
548 %13 = OpTypeSampler
549 %_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
550 %15 = OpTypeSampledImage %11
551 %v4float = OpTypeVector %float 4
552 %v2float = OpTypeVector %float 2
553 %_ptr_Output_v4float = OpTypePointer Output %v4float
554 %3 = OpVariable %_ptr_Output_v4float Output
555 %int = OpTypeInt 32 1
556 %_ptr_Input_int = OpTypePointer Input %int
557 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
558 %_struct_7 = OpTypeStruct %v4float
559 %_ptr_Output__struct_7 = OpTypePointer Output %_struct_7
560 %5 = OpVariable %_ptr_Output__struct_7 Output
561 %int_0 = OpConstant %int 0
562 %float_0 = OpConstant %float 0
563 %24 = OpConstantComposite %v2float %float_0 %float_0
564 %25 = OpVariable %_ptr_UniformConstant_11 UniformConstant
565 %26 = OpVariable %_ptr_UniformConstant_13 UniformConstant
566 %main = OpFunction %void None %9
567 %27 = OpLabel
568 OpLine %6 2 4
569 %28 = OpLoad %13 %26
570 %29 = OpLoad %11 %25
571 %30 = OpSampledImage %15 %29 %28
572 %31 = OpImageSampleImplicitLod %v4float %30 %24
573 OpLine %6 12 4
574 %41 = OpImageSampleProjImplicitLod %v4float %30 %24
575 %32 = OpAccessChain %_ptr_Output_v4float %5 %int_0
576 OpStore %32 %31
577 OpReturn
578 OpFunctionEnd)";
579
580 std::vector<Message> messages = {
581 {SPV_MSG_WARNING, "test.hlsl", 2, 4,
582 "Removing ImageSampleImplicitLod instruction because of incompatible "
583 "execution model."},
584 {SPV_MSG_WARNING, "test.hlsl", 12, 4,
585 "Removing ImageSampleProjImplicitLod instruction because of "
586 "incompatible "
587 "execution model."}};
588 SetMessageConsumer(GetTestMessageConsumer(messages));
589 auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
590 text, /* skip_nop = */ true, /* do_validation = */ false);
591 EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
592 }
593
594 } // namespace
595 } // namespace opt
596 } // namespace spvtools
597