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 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 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 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 } 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 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 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 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 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 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 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