SPIRV-Tools/test/opt/replace_invalid_opc_test.cpp
Steven Perron 82663f34c9
Check for unreachable blocks in merge-return. (#1966)
Merge return assumes that the only unreachable blocks are those needed
to keep the structured cfg valid.  Even those must be essentially empty
blocks.

If this is not the case, we get unpredictable behaviour.  This commit
add a check in merge return, and emits an error if it is not the case.

Added a pass of dead branch elimination before merge return in both the
performance and size passes.  It is a precondition of merge return.

Fixes #1962.
2018-10-10 15:18:15 -04:00

567 lines
23 KiB
C++

// Copyright (c) 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <cstdarg>
#include <string>
#include <vector>
#include "gmock/gmock.h"
#include "pass_utils.h"
#include "test/opt/assembly_builder.h"
#include "test/opt/pass_fixture.h"
namespace spvtools {
namespace opt {
namespace {
using ReplaceInvalidOpcodeTest = PassTest<::testing::Test>;
TEST_F(ReplaceInvalidOpcodeTest, ReplaceInstruction) {
const std::string text = R"(
; CHECK: [[special_const:%\w+]] = OpConstant %float -6.2598534e+18
; CHECK: [[constant:%\w+]] = OpConstantComposite %v4float [[special_const]] [[special_const]] [[special_const]] [[special_const]]
; CHECK-NOT: OpImageSampleImplicitLod
; CHECK: OpStore [[:%\w+]] [[constant]]
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
OpSource GLSL 400
OpSourceExtension "GL_ARB_separate_shader_objects"
OpSourceExtension "GL_ARB_shading_language_420pack"
OpName %main "main"
OpDecorate %3 Location 0
OpDecorate %gl_VertexIndex BuiltIn VertexIndex
OpMemberDecorate %_struct_6 0 BuiltIn Position
OpDecorate %_struct_6 Block
%void = OpTypeVoid
%8 = OpTypeFunction %void
%float = OpTypeFloat 32
%10 = OpTypeImage %float 2D 0 0 0 1 Unknown
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
%12 = OpTypeSampler
%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
%14 = OpTypeSampledImage %10
%v4float = OpTypeVector %float 4
%v2float = OpTypeVector %float 2
%_ptr_Output_v4float = OpTypePointer Output %v4float
%3 = OpVariable %_ptr_Output_v4float Output
%int = OpTypeInt 32 1
%_ptr_Input_int = OpTypePointer Input %int
%gl_VertexIndex = OpVariable %_ptr_Input_int Input
%_struct_6 = OpTypeStruct %v4float
%_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
%5 = OpVariable %_ptr_Output__struct_6 Output
%int_0 = OpConstant %int 0
%float_0 = OpConstant %float 0
%23 = OpConstantComposite %v2float %float_0 %float_0
%24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
%25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
%main = OpFunction %void None %8
%26 = OpLabel
%27 = OpLoad %12 %25
%28 = OpLoad %10 %24
%29 = OpSampledImage %14 %28 %27
%30 = OpImageSampleImplicitLod %v4float %29 %23
%31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
OpStore %31 %30
OpReturn
OpFunctionEnd)";
SinglePassRunAndMatch<ReplaceInvalidOpcodePass>(text, false);
}
TEST_F(ReplaceInvalidOpcodeTest, ReplaceInstructionInNonEntryPoint) {
const std::string text = R"(
; CHECK: [[special_const:%\w+]] = OpConstant %float -6.2598534e+18
; CHECK: [[constant:%\w+]] = OpConstantComposite %v4float [[special_const]] [[special_const]] [[special_const]] [[special_const]]
; CHECK-NOT: OpImageSampleImplicitLod
; CHECK: OpStore [[:%\w+]] [[constant]]
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
OpSource GLSL 400
OpSourceExtension "GL_ARB_separate_shader_objects"
OpSourceExtension "GL_ARB_shading_language_420pack"
OpName %main "main"
OpDecorate %3 Location 0
OpDecorate %gl_VertexIndex BuiltIn VertexIndex
OpMemberDecorate %_struct_6 0 BuiltIn Position
OpDecorate %_struct_6 Block
%void = OpTypeVoid
%8 = OpTypeFunction %void
%float = OpTypeFloat 32
%10 = OpTypeImage %float 2D 0 0 0 1 Unknown
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
%12 = OpTypeSampler
%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
%14 = OpTypeSampledImage %10
%v4float = OpTypeVector %float 4
%v2float = OpTypeVector %float 2
%_ptr_Output_v4float = OpTypePointer Output %v4float
%3 = OpVariable %_ptr_Output_v4float Output
%int = OpTypeInt 32 1
%_ptr_Input_int = OpTypePointer Input %int
%gl_VertexIndex = OpVariable %_ptr_Input_int Input
%_struct_6 = OpTypeStruct %v4float
%_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
%5 = OpVariable %_ptr_Output__struct_6 Output
%int_0 = OpConstant %int 0
%float_0 = OpConstant %float 0
%23 = OpConstantComposite %v2float %float_0 %float_0
%24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
%25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
%main = OpFunction %void None %8
%26 = OpLabel
%27 = OpFunctionCall %void %28
OpReturn
OpFunctionEnd
%28 = OpFunction %void None %8
%29 = OpLabel
%30 = OpLoad %12 %25
%31 = OpLoad %10 %24
%32 = OpSampledImage %14 %31 %30
%33 = OpImageSampleImplicitLod %v4float %32 %23
%34 = OpAccessChain %_ptr_Output_v4float %5 %int_0
OpStore %34 %33
OpReturn
OpFunctionEnd)";
SinglePassRunAndMatch<ReplaceInvalidOpcodePass>(text, false);
}
TEST_F(ReplaceInvalidOpcodeTest, ReplaceInstructionMultipleEntryPoints) {
const std::string text = R"(
; CHECK: [[special_const:%\w+]] = OpConstant %float -6.2598534e+18
; CHECK: [[constant:%\w+]] = OpConstantComposite %v4float [[special_const]] [[special_const]] [[special_const]] [[special_const]]
; CHECK-NOT: OpImageSampleImplicitLod
; CHECK: OpStore [[:%\w+]] [[constant]]
; CHECK-NOT: OpImageSampleImplicitLod
; CHECK: OpStore [[:%\w+]] [[constant]]
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
OpEntryPoint Vertex %main2 "main2" %3 %gl_VertexIndex %5
OpSource GLSL 400
OpSourceExtension "GL_ARB_separate_shader_objects"
OpSourceExtension "GL_ARB_shading_language_420pack"
OpName %main "main"
OpName %main2 "main2"
OpDecorate %3 Location 0
OpDecorate %gl_VertexIndex BuiltIn VertexIndex
OpMemberDecorate %_struct_6 0 BuiltIn Position
OpDecorate %_struct_6 Block
%void = OpTypeVoid
%8 = OpTypeFunction %void
%float = OpTypeFloat 32
%10 = OpTypeImage %float 2D 0 0 0 1 Unknown
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
%12 = OpTypeSampler
%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
%14 = OpTypeSampledImage %10
%v4float = OpTypeVector %float 4
%v2float = OpTypeVector %float 2
%_ptr_Output_v4float = OpTypePointer Output %v4float
%3 = OpVariable %_ptr_Output_v4float Output
%int = OpTypeInt 32 1
%_ptr_Input_int = OpTypePointer Input %int
%gl_VertexIndex = OpVariable %_ptr_Input_int Input
%_struct_6 = OpTypeStruct %v4float
%_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
%5 = OpVariable %_ptr_Output__struct_6 Output
%int_0 = OpConstant %int 0
%float_0 = OpConstant %float 0
%23 = OpConstantComposite %v2float %float_0 %float_0
%24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
%25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
%main = OpFunction %void None %8
%26 = OpLabel
%27 = OpLoad %12 %25
%28 = OpLoad %10 %24
%29 = OpSampledImage %14 %28 %27
%30 = OpImageSampleImplicitLod %v4float %29 %23
%31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
OpStore %31 %30
OpReturn
OpFunctionEnd
%main2 = OpFunction %void None %8
%46 = OpLabel
%47 = OpLoad %12 %25
%48 = OpLoad %10 %24
%49 = OpSampledImage %14 %48 %47
%50 = OpImageSampleImplicitLod %v4float %49 %23
%51 = OpAccessChain %_ptr_Output_v4float %5 %int_0
OpStore %51 %50
OpReturn
OpFunctionEnd)";
SinglePassRunAndMatch<ReplaceInvalidOpcodePass>(text, false);
}
TEST_F(ReplaceInvalidOpcodeTest, DontReplaceInstruction) {
const std::string text = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %3 %gl_VertexIndex %5
OpSource GLSL 400
OpSourceExtension "GL_ARB_separate_shader_objects"
OpSourceExtension "GL_ARB_shading_language_420pack"
OpName %main "main"
OpDecorate %3 Location 0
OpDecorate %gl_VertexIndex BuiltIn VertexIndex
OpMemberDecorate %_struct_6 0 BuiltIn Position
OpDecorate %_struct_6 Block
%void = OpTypeVoid
%8 = OpTypeFunction %void
%float = OpTypeFloat 32
%10 = OpTypeImage %float 2D 0 0 0 1 Unknown
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
%12 = OpTypeSampler
%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
%14 = OpTypeSampledImage %10
%v4float = OpTypeVector %float 4
%v2float = OpTypeVector %float 2
%_ptr_Output_v4float = OpTypePointer Output %v4float
%3 = OpVariable %_ptr_Output_v4float Output
%int = OpTypeInt 32 1
%_ptr_Input_int = OpTypePointer Input %int
%gl_VertexIndex = OpVariable %_ptr_Input_int Input
%_struct_6 = OpTypeStruct %v4float
%_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
%5 = OpVariable %_ptr_Output__struct_6 Output
%int_0 = OpConstant %int 0
%float_0 = OpConstant %float 0
%23 = OpConstantComposite %v2float %float_0 %float_0
%24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
%25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
%main = OpFunction %void None %8
%26 = OpLabel
%27 = OpLoad %12 %25
%28 = OpLoad %10 %24
%29 = OpSampledImage %14 %28 %27
%30 = OpImageSampleImplicitLod %v4float %29 %23
%31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
OpStore %31 %30
OpReturn
OpFunctionEnd)";
auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
text, /* skip_nop = */ true, /* do_validation = */ false);
EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
}
TEST_F(ReplaceInvalidOpcodeTest, MultipleEntryPointsDifferentStage) {
const std::string text = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
OpEntryPoint Fragment %main2 "main2" %3 %gl_VertexIndex %5
OpSource GLSL 400
OpSourceExtension "GL_ARB_separate_shader_objects"
OpSourceExtension "GL_ARB_shading_language_420pack"
OpName %main "main"
OpName %main2 "main2"
OpDecorate %3 Location 0
OpDecorate %gl_VertexIndex BuiltIn VertexIndex
OpMemberDecorate %_struct_6 0 BuiltIn Position
OpDecorate %_struct_6 Block
%void = OpTypeVoid
%8 = OpTypeFunction %void
%float = OpTypeFloat 32
%10 = OpTypeImage %float 2D 0 0 0 1 Unknown
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
%12 = OpTypeSampler
%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
%14 = OpTypeSampledImage %10
%v4float = OpTypeVector %float 4
%v2float = OpTypeVector %float 2
%_ptr_Output_v4float = OpTypePointer Output %v4float
%3 = OpVariable %_ptr_Output_v4float Output
%int = OpTypeInt 32 1
%_ptr_Input_int = OpTypePointer Input %int
%gl_VertexIndex = OpVariable %_ptr_Input_int Input
%_struct_6 = OpTypeStruct %v4float
%_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
%5 = OpVariable %_ptr_Output__struct_6 Output
%int_0 = OpConstant %int 0
%float_0 = OpConstant %float 0
%23 = OpConstantComposite %v2float %float_0 %float_0
%24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
%25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
%main = OpFunction %void None %8
%26 = OpLabel
%27 = OpLoad %12 %25
%28 = OpLoad %10 %24
%29 = OpSampledImage %14 %28 %27
%30 = OpImageSampleImplicitLod %v4float %29 %23
%31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
OpStore %31 %30
OpReturn
OpFunctionEnd
%main2 = OpFunction %void None %8
%46 = OpLabel
%47 = OpLoad %12 %25
%48 = OpLoad %10 %24
%49 = OpSampledImage %14 %48 %47
%50 = OpImageSampleImplicitLod %v4float %49 %23
%51 = OpAccessChain %_ptr_Output_v4float %5 %int_0
OpStore %51 %50
OpReturn
OpFunctionEnd)";
auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
text, /* skip_nop = */ true, /* do_validation = */ false);
EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
}
TEST_F(ReplaceInvalidOpcodeTest, DontReplaceLinkage) {
const std::string text = R"(
OpCapability Shader
OpCapability Linkage
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
OpSource GLSL 400
OpSourceExtension "GL_ARB_separate_shader_objects"
OpSourceExtension "GL_ARB_shading_language_420pack"
OpName %main "main"
OpDecorate %3 Location 0
OpDecorate %gl_VertexIndex BuiltIn VertexIndex
OpMemberDecorate %_struct_6 0 BuiltIn Position
OpDecorate %_struct_6 Block
%void = OpTypeVoid
%8 = OpTypeFunction %void
%float = OpTypeFloat 32
%10 = OpTypeImage %float 2D 0 0 0 1 Unknown
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
%12 = OpTypeSampler
%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
%14 = OpTypeSampledImage %10
%v4float = OpTypeVector %float 4
%v2float = OpTypeVector %float 2
%_ptr_Output_v4float = OpTypePointer Output %v4float
%3 = OpVariable %_ptr_Output_v4float Output
%int = OpTypeInt 32 1
%_ptr_Input_int = OpTypePointer Input %int
%gl_VertexIndex = OpVariable %_ptr_Input_int Input
%_struct_6 = OpTypeStruct %v4float
%_ptr_Output__struct_6 = OpTypePointer Output %_struct_6
%5 = OpVariable %_ptr_Output__struct_6 Output
%int_0 = OpConstant %int 0
%float_0 = OpConstant %float 0
%23 = OpConstantComposite %v2float %float_0 %float_0
%24 = OpVariable %_ptr_UniformConstant_10 UniformConstant
%25 = OpVariable %_ptr_UniformConstant_12 UniformConstant
%main = OpFunction %void None %8
%26 = OpLabel
%27 = OpLoad %12 %25
%28 = OpLoad %10 %24
%29 = OpSampledImage %14 %28 %27
%30 = OpImageSampleImplicitLod %v4float %29 %23
%31 = OpAccessChain %_ptr_Output_v4float %5 %int_0
OpStore %31 %30
OpReturn
OpFunctionEnd)";
auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
text, /* skip_nop = */ true, /* do_validation = */ false);
EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
}
TEST_F(ReplaceInvalidOpcodeTest, BarrierDontReplace) {
const std::string text = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
OpSource GLSL 450
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
OpSourceExtension "GL_GOOGLE_include_directive"
OpName %main "main"
%void = OpTypeVoid
%3 = OpTypeFunction %void
%uint = OpTypeInt 32 0
%uint_2 = OpConstant %uint 2
%uint_264 = OpConstant %uint 264
%main = OpFunction %void None %3
%5 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264
OpReturn
OpFunctionEnd)";
auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
text, /* skip_nop = */ true, /* do_validation = */ false);
EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
}
TEST_F(ReplaceInvalidOpcodeTest, BarrierReplace) {
const std::string text = R"(
; CHECK-NOT: OpControlBarrier
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main"
OpExecutionMode %main LocalSize 1 1 1
OpSource GLSL 450
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
OpSourceExtension "GL_GOOGLE_include_directive"
OpName %main "main"
%void = OpTypeVoid
%3 = OpTypeFunction %void
%uint = OpTypeInt 32 0
%uint_2 = OpConstant %uint 2
%uint_264 = OpConstant %uint 264
%main = OpFunction %void None %3
%5 = OpLabel
OpControlBarrier %uint_2 %uint_2 %uint_264
OpReturn
OpFunctionEnd)";
SinglePassRunAndMatch<ReplaceInvalidOpcodePass>(text, false);
}
TEST_F(ReplaceInvalidOpcodeTest, MessageTest) {
const std::string text = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
OpSource GLSL 400
%6 = OpString "test.hlsl"
OpSourceExtension "GL_ARB_separate_shader_objects"
OpSourceExtension "GL_ARB_shading_language_420pack"
OpName %main "main"
OpDecorate %3 Location 0
OpDecorate %gl_VertexIndex BuiltIn VertexIndex
OpMemberDecorate %_struct_7 0 BuiltIn Position
OpDecorate %_struct_7 Block
%void = OpTypeVoid
%9 = OpTypeFunction %void
%float = OpTypeFloat 32
%11 = OpTypeImage %float 2D 0 0 0 1 Unknown
%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
%13 = OpTypeSampler
%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
%15 = OpTypeSampledImage %11
%v4float = OpTypeVector %float 4
%v2float = OpTypeVector %float 2
%_ptr_Output_v4float = OpTypePointer Output %v4float
%3 = OpVariable %_ptr_Output_v4float Output
%int = OpTypeInt 32 1
%_ptr_Input_int = OpTypePointer Input %int
%gl_VertexIndex = OpVariable %_ptr_Input_int Input
%_struct_7 = OpTypeStruct %v4float
%_ptr_Output__struct_7 = OpTypePointer Output %_struct_7
%5 = OpVariable %_ptr_Output__struct_7 Output
%int_0 = OpConstant %int 0
%float_0 = OpConstant %float 0
%24 = OpConstantComposite %v2float %float_0 %float_0
%25 = OpVariable %_ptr_UniformConstant_11 UniformConstant
%26 = OpVariable %_ptr_UniformConstant_13 UniformConstant
%main = OpFunction %void None %9
%27 = OpLabel
OpLine %6 2 4
%28 = OpLoad %13 %26
%29 = OpLoad %11 %25
%30 = OpSampledImage %15 %29 %28
%31 = OpImageSampleImplicitLod %v4float %30 %24
%32 = OpAccessChain %_ptr_Output_v4float %5 %int_0
OpStore %32 %31
OpReturn
OpFunctionEnd)";
std::vector<Message> messages = {
{SPV_MSG_WARNING, "test.hlsl", 2, 4,
"Removing ImageSampleImplicitLod instruction because of incompatible "
"execution model."}};
SetMessageConsumer(GetTestMessageConsumer(messages));
auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
text, /* skip_nop = */ true, /* do_validation = */ false);
EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
}
TEST_F(ReplaceInvalidOpcodeTest, MultipleMessageTest) {
const std::string text = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %3 %gl_VertexIndex %5
OpSource GLSL 400
%6 = OpString "test.hlsl"
OpSourceExtension "GL_ARB_separate_shader_objects"
OpSourceExtension "GL_ARB_shading_language_420pack"
OpName %main "main"
OpDecorate %3 Location 0
OpDecorate %gl_VertexIndex BuiltIn VertexIndex
OpMemberDecorate %_struct_7 0 BuiltIn Position
OpDecorate %_struct_7 Block
%void = OpTypeVoid
%9 = OpTypeFunction %void
%float = OpTypeFloat 32
%11 = OpTypeImage %float 2D 0 0 0 1 Unknown
%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
%13 = OpTypeSampler
%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
%15 = OpTypeSampledImage %11
%v4float = OpTypeVector %float 4
%v2float = OpTypeVector %float 2
%_ptr_Output_v4float = OpTypePointer Output %v4float
%3 = OpVariable %_ptr_Output_v4float Output
%int = OpTypeInt 32 1
%_ptr_Input_int = OpTypePointer Input %int
%gl_VertexIndex = OpVariable %_ptr_Input_int Input
%_struct_7 = OpTypeStruct %v4float
%_ptr_Output__struct_7 = OpTypePointer Output %_struct_7
%5 = OpVariable %_ptr_Output__struct_7 Output
%int_0 = OpConstant %int 0
%float_0 = OpConstant %float 0
%24 = OpConstantComposite %v2float %float_0 %float_0
%25 = OpVariable %_ptr_UniformConstant_11 UniformConstant
%26 = OpVariable %_ptr_UniformConstant_13 UniformConstant
%main = OpFunction %void None %9
%27 = OpLabel
OpLine %6 2 4
%28 = OpLoad %13 %26
%29 = OpLoad %11 %25
%30 = OpSampledImage %15 %29 %28
%31 = OpImageSampleImplicitLod %v4float %30 %24
OpLine %6 12 4
%41 = OpImageSampleProjImplicitLod %v4float %30 %24
%32 = OpAccessChain %_ptr_Output_v4float %5 %int_0
OpStore %32 %31
OpReturn
OpFunctionEnd)";
std::vector<Message> messages = {
{SPV_MSG_WARNING, "test.hlsl", 2, 4,
"Removing ImageSampleImplicitLod instruction because of incompatible "
"execution model."},
{SPV_MSG_WARNING, "test.hlsl", 12, 4,
"Removing ImageSampleProjImplicitLod instruction because of "
"incompatible "
"execution model."}};
SetMessageConsumer(GetTestMessageConsumer(messages));
auto result = SinglePassRunAndDisassemble<ReplaceInvalidOpcodePass>(
text, /* skip_nop = */ true, /* do_validation = */ false);
EXPECT_EQ(Pass::Status::SuccessWithChange, std::get<1>(result));
}
} // namespace
} // namespace opt
} // namespace spvtools