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