aboutsummaryrefslogtreecommitdiff
path: root/test/opt/aggressive_dead_code_elim_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/opt/aggressive_dead_code_elim_test.cpp')
-rw-r--r--test/opt/aggressive_dead_code_elim_test.cpp458
1 files changed, 453 insertions, 5 deletions
diff --git a/test/opt/aggressive_dead_code_elim_test.cpp b/test/opt/aggressive_dead_code_elim_test.cpp
index 5b4291da..f228c8cb 100644
--- a/test/opt/aggressive_dead_code_elim_test.cpp
+++ b/test/opt/aggressive_dead_code_elim_test.cpp
@@ -7063,6 +7063,287 @@ TEST_F(AggressiveDCETest, DebugInfoKeepInFunctionElimStoreVar) {
SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
}
+TEST_F(AggressiveDCETest, ShaderDebugInfoKeepInFunctionElimStoreVar) {
+ // Verify that dead local variable tc and store eliminated but all
+ // in-function NonSemantic Shader debuginfo kept.
+
+ const std::string text = R"(
+ OpCapability Shader
+ OpExtension "SPV_KHR_non_semantic_info"
+ %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %g_sAniso %in_var_TEXCOORD2 %out_var_SV_Target0
+ OpExecutionMode %MainPs OriginUpperLeft
+ %7 = OpString "foo.frag"
+ %8 = OpString "PS_OUTPUT"
+ %9 = OpString "float"
+ %10 = OpString "vColor"
+ %11 = OpString "PS_INPUT"
+ %12 = OpString "vTextureCoords"
+ %13 = OpString "@type.2d.image"
+ %14 = OpString "type.2d.image"
+ %15 = OpString "Texture2D.TemplateParam"
+ %16 = OpString "src.MainPs"
+ %17 = OpString "tc"
+ %18 = OpString "ps_output"
+ %19 = OpString "i"
+ %20 = OpString "@type.sampler"
+ %21 = OpString "type.sampler"
+ %22 = OpString "g_sAniso"
+ %23 = OpString "g_tColor"
+ OpName %type_2d_image "type.2d.image"
+ OpName %g_tColor "g_tColor"
+ OpName %type_sampler "type.sampler"
+ OpName %g_sAniso "g_sAniso"
+ OpName %in_var_TEXCOORD2 "in.var.TEXCOORD2"
+ OpName %out_var_SV_Target0 "out.var.SV_Target0"
+ OpName %MainPs "MainPs"
+ OpName %PS_INPUT "PS_INPUT"
+ OpMemberName %PS_INPUT 0 "vTextureCoords"
+ OpName %param_var_i "param.var.i"
+ OpName %PS_OUTPUT "PS_OUTPUT"
+ OpMemberName %PS_OUTPUT 0 "vColor"
+ OpName %type_sampled_image "type.sampled.image"
+ OpDecorate %in_var_TEXCOORD2 Location 0
+ OpDecorate %out_var_SV_Target0 Location 0
+ OpDecorate %g_tColor DescriptorSet 0
+ OpDecorate %g_tColor Binding 0
+ OpDecorate %g_sAniso DescriptorSet 0
+ OpDecorate %g_sAniso Binding 1
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %uint = OpTypeInt 32 0
+ %uint_32 = OpConstant %uint 32
+ %float = OpTypeFloat 32
+%type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
+%_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
+%type_sampler = OpTypeSampler
+%_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
+ %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %void = OpTypeVoid
+ %uint_128 = OpConstant %uint 128
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_2 = OpConstant %uint 2
+ %uint_3 = OpConstant %uint 3
+ %uint_4 = OpConstant %uint 4
+ %uint_5 = OpConstant %uint 5
+ %uint_7 = OpConstant %uint 7
+ %uint_8 = OpConstant %uint 8
+ %uint_10 = OpConstant %uint 10
+ %uint_11 = OpConstant %uint 11
+ %uint_12 = OpConstant %uint 12
+ %uint_14 = OpConstant %uint 14
+ %uint_15 = OpConstant %uint 15
+ %uint_16 = OpConstant %uint 16
+ %uint_17 = OpConstant %uint 17
+ %uint_19 = OpConstant %uint 19
+ %uint_20 = OpConstant %uint 20
+ %uint_21 = OpConstant %uint 21
+ %uint_25 = OpConstant %uint 25
+ %uint_29 = OpConstant %uint 29
+ %uint_30 = OpConstant %uint 30
+ %uint_35 = OpConstant %uint 35
+ %uint_41 = OpConstant %uint 41
+ %uint_48 = OpConstant %uint 48
+ %uint_53 = OpConstant %uint 53
+ %uint_64 = OpConstant %uint 64
+ %45 = OpTypeFunction %void
+ %PS_INPUT = OpTypeStruct %v2float
+%_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
+ %PS_OUTPUT = OpTypeStruct %v4float
+ %47 = OpTypeFunction %PS_OUTPUT %_ptr_Function_PS_INPUT
+%_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
+%_ptr_Function_v2float = OpTypePointer Function %v2float
+%type_sampled_image = OpTypeSampledImage %type_2d_image
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+ %g_tColor = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
+ %g_sAniso = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
+%in_var_TEXCOORD2 = OpVariable %_ptr_Input_v2float Input
+%out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
+ %51 = OpExtInst %void %1 DebugInfoNone
+ %52 = OpExtInst %void %1 DebugExpression
+ %53 = OpExtInst %void %1 DebugOperation %uint_0
+ %54 = OpExtInst %void %1 DebugExpression %53
+ %55 = OpExtInst %void %1 DebugSource %7
+ %56 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %55 %uint_5
+ %59 = OpExtInst %void %1 DebugTypeBasic %9 %uint_32 %uint_3 %uint_0
+ %60 = OpExtInst %void %1 DebugTypeVector %59 %uint_4
+ %58 = OpExtInst %void %1 DebugTypeMember %10 %60 %55 %uint_12 %uint_5 %uint_0 %uint_128 %uint_3
+ %57 = OpExtInst %void %1 DebugTypeComposite %8 %uint_1 %55 %uint_10 %uint_1 %56 %8 %uint_128 %uint_3 %58
+ %63 = OpExtInst %void %1 DebugTypeVector %59 %uint_2
+ %62 = OpExtInst %void %1 DebugTypeMember %12 %63 %55 %uint_7 %uint_5 %uint_0 %uint_64 %uint_3
+ %61 = OpExtInst %void %1 DebugTypeComposite %11 %uint_1 %55 %uint_5 %uint_1 %56 %11 %uint_64 %uint_3 %62
+ %64 = OpExtInst %void %1 DebugTypeComposite %13 %uint_0 %55 %uint_0 %uint_0 %56 %14 %51 %uint_3
+ %67 = OpExtInst %void %1 DebugTypeFunction %uint_3 %57 %61
+ %68 = OpExtInst %void %1 DebugFunction %16 %67 %55 %uint_15 %uint_1 %56 %16 %uint_3 %uint_16
+ %69 = OpExtInst %void %1 DebugLexicalBlock %55 %uint_16 %uint_1 %68
+ %70 = OpExtInst %void %1 DebugLocalVariable %17 %63 %55 %uint_19 %uint_12 %69 %uint_4
+ %71 = OpExtInst %void %1 DebugLocalVariable %18 %57 %55 %uint_17 %uint_15 %69 %uint_4
+ %72 = OpExtInst %void %1 DebugLocalVariable %19 %61 %55 %uint_15 %uint_29 %68 %uint_4 %uint_1
+ %73 = OpExtInst %void %1 DebugTypeComposite %20 %uint_1 %55 %uint_0 %uint_0 %56 %21 %51 %uint_3
+ %74 = OpExtInst %void %1 DebugGlobalVariable %22 %73 %55 %uint_3 %uint_14 %56 %22 %g_sAniso %uint_8
+ %75 = OpExtInst %void %1 DebugGlobalVariable %23 %64 %55 %uint_1 %uint_11 %56 %23 %g_tColor %uint_8
+ %MainPs = OpFunction %void None %45
+ %76 = OpLabel
+ %78 = OpVariable %_ptr_Function_PS_OUTPUT Function
+ %79 = OpVariable %_ptr_Function_v2float Function
+ %81 = OpVariable %_ptr_Function_PS_OUTPUT Function
+%param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
+ %82 = OpLoad %v2float %in_var_TEXCOORD2
+ %83 = OpCompositeConstruct %PS_INPUT %82
+ OpStore %param_var_i %83
+ %112 = OpExtInst %void %1 DebugFunctionDefinition %68 %MainPs
+ %109 = OpExtInst %void %1 DebugScope %68
+ %85 = OpExtInst %void %1 DebugDeclare %72 %param_var_i %52
+ %110 = OpExtInst %void %1 DebugScope %69
+ %87 = OpExtInst %void %1 DebugDeclare %71 %78 %52
+;CHECK: {{%\w+}} = OpExtInst %void %1 DebugFunctionDefinition %68 %MainPs
+;CHECK: {{%\w+}} = OpExtInst %void %1 DebugScope %68
+;CHECK: {{%\w+}} = OpExtInst %void %1 DebugDeclare %72 %param_var_i %52
+;CHECK: {{%\w+}} = OpExtInst %void %1 DebugScope %69
+;CHECK: {{%\w+}} = OpExtInst %void %1 DebugDeclare %71 %78 %52
+ %300 = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_17 %uint_30
+;CHECK: {{%\w+}} = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_17 %uint_30
+ %88 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_0
+ %89 = OpLoad %v2float %88
+ %301 = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_12 %uint_35
+ OpStore %79 %89
+;CHECK-NOT: OpStore %79 %89
+ %302 = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_12 %uint_35
+;CHECK: {{%\w+}} = OpExtInst %void %1 DebugLine %55 %uint_19 %uint_19 %uint_12 %uint_35
+ %106 = OpExtInst %void %1 DebugValue %70 %89 %52
+;CHECK: {{%\w+}} = OpExtInst %void %1 DebugValue %70 %89 %52
+ %303 = OpExtInst %void %1 DebugLine %55 %uint_20 %uint_20 %uint_25 %uint_32
+ %91 = OpLoad %type_2d_image %g_tColor
+ %304 = OpExtInst %void %1 DebugLine %55 %uint_20 %uint_20 %uint_41 %uint_48
+ %92 = OpLoad %type_sampler %g_sAniso
+ %305 = OpExtInst %void %1 DebugLine %55 %uint_20 %uint_20 %uint_25 %uint_53
+ %94 = OpSampledImage %type_sampled_image %91 %92
+ %95 = OpImageSampleImplicitLod %v4float %94 %89 None
+ %306 = OpExtInst %void %1 DebugLine %55 %uint_20 %uint_20 %uint_5 %uint_53
+ %96 = OpAccessChain %_ptr_Function_v4float %78 %int_0
+ OpStore %96 %95
+ %307 = OpExtInst %void %1 DebugLine %55 %uint_21 %uint_21 %uint_12 %uint_20
+ %97 = OpLoad %PS_OUTPUT %78
+ %308 = OpExtInst %void %1 DebugLine %55 %uint_21 %uint_21 %uint_5 %uint_20
+ OpStore %81 %97
+ %309 = OpExtInst %void %1 DebugNoLine
+;CHECK: {{%\w+}} = OpExtInst %void %1 DebugNoLine
+ %111 = OpExtInst %void %1 DebugNoScope
+;CHECK: {{%\w+}} = OpExtInst %void %1 DebugNoScope
+ %100 = OpCompositeExtract %v4float %97 0
+ OpStore %out_var_SV_Target0 %100
+ OpReturn
+ OpFunctionEnd
+)";
+
+ SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
+}
+
+TEST_F(AggressiveDCETest, ShaderDebugInfoGlobalDCE) {
+ // Verify that DebugGlobalVariable for eliminated private variable has
+ // variable operand replaced with DebugInfoNone.
+
+ const std::string text = R"(OpCapability Shader
+OpExtension "SPV_KHR_non_semantic_info"
+%1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %MainPs "MainPs" %out_var_SV_Target0 %a
+OpExecutionMode %MainPs OriginUpperLeft
+%5 = OpString "source2.hlsl"
+%24 = OpString "float"
+%29 = OpString "vColor"
+%33 = OpString "PS_OUTPUT"
+%37 = OpString "MainPs"
+%38 = OpString ""
+%42 = OpString "ps_output"
+%46 = OpString "a"
+OpName %a "a"
+OpName %out_var_SV_Target0 "out.var.SV_Target0"
+OpName %MainPs "MainPs"
+OpName %PS_OUTPUT "PS_OUTPUT"
+OpMemberName %PS_OUTPUT 0 "vColor"
+OpDecorate %out_var_SV_Target0 Location 0
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%8 = OpConstantNull %v4float
+%float_0 = OpConstant %float 0
+%10 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%uint = OpTypeInt 32 0
+%uint_32 = OpConstant %uint 32
+%_ptr_Private_v4float = OpTypePointer Private %v4float
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%void = OpTypeVoid
+%uint_1 = OpConstant %uint 1
+%uint_4 = OpConstant %uint 4
+%uint_5 = OpConstant %uint 5
+%uint_3 = OpConstant %uint 3
+%uint_0 = OpConstant %uint 0
+%uint_128 = OpConstant %uint 128
+%uint_12 = OpConstant %uint 12
+%uint_8 = OpConstant %uint 8
+%uint_9 = OpConstant %uint 9
+%uint_10 = OpConstant %uint 10
+%uint_15 = OpConstant %uint 15
+%48 = OpTypeFunction %void
+%PS_OUTPUT = OpTypeStruct %v4float
+%54 = OpTypeFunction %PS_OUTPUT
+%_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%a = OpVariable %_ptr_Private_v4float Private
+;CHECK-NOT: %a = OpVariable %_ptr_Private_v4float Private
+%out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
+;CHECK: [[dbg_none:%\w+]] = OpExtInst %void %1 DebugInfoNone
+%18 = OpExtInst %void %1 DebugExpression
+%19 = OpExtInst %void %1 DebugSource %5
+%20 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %19 %uint_5
+%25 = OpExtInst %void %1 DebugTypeBasic %24 %uint_32 %uint_3 %uint_0
+%28 = OpExtInst %void %1 DebugTypeVector %25 %uint_4
+%31 = OpExtInst %void %1 DebugTypeMember %29 %28 %19 %uint_5 %uint_12 %uint_0 %uint_128 %uint_3
+%34 = OpExtInst %void %1 DebugTypeComposite %33 %uint_1 %19 %uint_3 %uint_8 %20 %33 %uint_128 %uint_3 %31
+%36 = OpExtInst %void %1 DebugTypeFunction %uint_3 %34
+%39 = OpExtInst %void %1 DebugFunction %37 %36 %19 %uint_8 %uint_1 %20 %38 %uint_3 %uint_9
+%41 = OpExtInst %void %1 DebugLexicalBlock %19 %uint_9 %uint_1 %39
+%43 = OpExtInst %void %1 DebugLocalVariable %42 %34 %19 %uint_10 %uint_15 %41 %uint_4
+%47 = OpExtInst %void %1 DebugGlobalVariable %46 %28 %19 %uint_1 %uint_15 %20 %46 %a %uint_8
+;CHECK: %47 = OpExtInst %void %1 DebugGlobalVariable %46 %28 %19 %uint_1 %uint_15 %20 %46 [[dbg_none]] %uint_8
+%MainPs = OpFunction %void None %48
+%49 = OpLabel
+%65 = OpVariable %_ptr_Function_PS_OUTPUT Function
+%66 = OpVariable %_ptr_Function_PS_OUTPUT Function
+OpStore %a %8
+%72 = OpExtInst %void %1 DebugScope %41
+%69 = OpExtInst %void %1 DebugDeclare %43 %65 %18
+OpLine %5 11 5
+%70 = OpAccessChain %_ptr_Function_v4float %65 %int_0
+OpStore %70 %10
+OpLine %5 12 12
+%71 = OpLoad %PS_OUTPUT %65
+OpLine %5 12 5
+OpStore %66 %71
+%73 = OpExtInst %void %1 DebugNoLine
+%74 = OpExtInst %void %1 DebugNoScope
+%51 = OpLoad %PS_OUTPUT %66
+%53 = OpCompositeExtract %v4float %51 0
+OpStore %out_var_SV_Target0 %53
+OpLine %5 13 1
+OpReturn
+OpFunctionEnd
+)";
+
+ SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
+}
+
TEST_F(AggressiveDCETest, DebugInfoDeclareKeepsStore) {
// Verify that local variable tc and its store are kept by DebugDeclare.
//
@@ -7584,11 +7865,178 @@ TEST_F(AggressiveDCETest, KeepDebugScopeParent) {
SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
}
-// TODO(greg-lunarg): Add tests to verify handling of these cases:
-//
-// Check that logical addressing required
-// Check that function calls inhibit optimization
-// Others?
+TEST_F(AggressiveDCETest, KeepExportFunctions) {
+ // All functions are reachable. In particular, ExportedFunc and Constant are
+ // reachable because ExportedFunc is exported. Nothing should be removed.
+ const std::vector<const char*> text = {
+ // clang-format off
+ "OpCapability Shader",
+ "OpCapability Linkage",
+ "OpMemoryModel Logical GLSL450",
+ "OpEntryPoint Fragment %main \"main\"",
+ "OpName %main \"main\"",
+ "OpName %ExportedFunc \"ExportedFunc\"",
+ "OpName %Live \"Live\"",
+ "OpDecorate %ExportedFunc LinkageAttributes \"ExportedFunc\" Export",
+ "%void = OpTypeVoid",
+ "%7 = OpTypeFunction %void",
+ "%main = OpFunction %void None %7",
+ "%15 = OpLabel",
+ "OpReturn",
+ "OpFunctionEnd",
+"%ExportedFunc = OpFunction %void None %7",
+ "%19 = OpLabel",
+ "%16 = OpFunctionCall %void %Live",
+ "OpReturn",
+ "OpFunctionEnd",
+ "%Live = OpFunction %void None %7",
+ "%20 = OpLabel",
+ "OpReturn",
+ "OpFunctionEnd"
+ // clang-format on
+ };
+
+ SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ std::string assembly = JoinAllInsts(text);
+ auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
+ assembly, /* skip_nop = */ true, /* do_validation = */ false);
+ EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
+ EXPECT_EQ(assembly, std::get<0>(result));
+}
+
+TEST_F(AggressiveDCETest, KeepPrivateVarInExportFunctions) {
+ // The loads and stores from the private variable should not be removed
+ // because the functions are exported and could be called.
+ const std::string text = R"(OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+OpSource HLSL 630
+OpName %privateVar "privateVar"
+OpName %ReadPrivate "ReadPrivate"
+OpName %WritePrivate "WritePrivate"
+OpName %value "value"
+OpDecorate %ReadPrivate LinkageAttributes "ReadPrivate" Export
+OpDecorate %WritePrivate LinkageAttributes "WritePrivate" Export
+%int = OpTypeInt 32 1
+%_ptr_Private_int = OpTypePointer Private %int
+%6 = OpTypeFunction %int
+%void = OpTypeVoid
+%_ptr_Function_int = OpTypePointer Function %int
+%10 = OpTypeFunction %void %_ptr_Function_int
+%privateVar = OpVariable %_ptr_Private_int Private
+%ReadPrivate = OpFunction %int None %6
+%12 = OpLabel
+%8 = OpLoad %int %privateVar
+OpReturnValue %8
+OpFunctionEnd
+%WritePrivate = OpFunction %void None %10
+%value = OpFunctionParameter %_ptr_Function_int
+%13 = OpLabel
+%14 = OpLoad %int %value
+OpStore %privateVar %14
+OpReturn
+OpFunctionEnd
+)";
+
+ SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
+ text, /* skip_nop = */ true, /* do_validation = */ false);
+ EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
+ EXPECT_EQ(text, std::get<0>(result));
+}
+
+TEST_F(AggressiveDCETest, KeepLableNames) {
+ const std::string text = R"(OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+OpSource HLSL 630
+OpName %WritePrivate "WritePrivate"
+OpName %entry "entry"
+OpName %target "target"
+OpDecorate %WritePrivate LinkageAttributes "WritePrivate" Export
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%WritePrivate = OpFunction %void None %3
+%entry = OpLabel
+OpBranch %target
+%target = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
+ text, /* skip_nop = */ true, /* do_validation = */ false);
+ EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
+ EXPECT_EQ(text, std::get<0>(result));
+}
+
+TEST_F(AggressiveDCETest, PreserveInterface) {
+ // Set preserve_interface to true. Verify that unused uniform
+ // constant in entry point interface is not eliminated.
+ const std::string text = R"(OpCapability RayTracingKHR
+OpExtension "SPV_KHR_ray_tracing"
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint RayGenerationNV %2 "main" %3 %4
+OpDecorate %3 Location 0
+OpDecorate %4 DescriptorSet 2
+OpDecorate %4 Binding 0
+%void = OpTypeVoid
+%6 = OpTypeFunction %void
+%uint = OpTypeInt 32 0
+%uint_0 = OpConstant %uint 0
+%float = OpTypeFloat 32
+%_ptr_CallableDataNV_float = OpTypePointer CallableDataNV %float
+%3 = OpVariable %_ptr_CallableDataNV_float CallableDataNV
+%13 = OpTypeAccelerationStructureKHR
+%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
+%4 = OpVariable %_ptr_UniformConstant_13 UniformConstant
+%2 = OpFunction %void None %6
+%15 = OpLabel
+OpExecuteCallableKHR %uint_0 %3
+OpReturn
+OpFunctionEnd
+)";
+
+ SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ auto result = SinglePassRunAndDisassemble<AggressiveDCEPass>(
+ text, /* skip_nop = */ true, /* do_validation = */ false,
+ /* preserve_interface */ true);
+ EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result));
+ EXPECT_EQ(text, std::get<0>(result));
+}
+
+TEST_F(AggressiveDCETest, EmptyContinueWithConditionalBranch) {
+ const std::string text = R"(OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %2 "main"
+OpExecutionMode %2 OriginUpperLeft
+%void = OpTypeVoid
+%4 = OpTypeFunction %void
+%bool = OpTypeBool
+%false = OpConstantFalse %bool
+%2 = OpFunction %void None %4
+%9 = OpLabel
+OpBranch %10
+%10 = OpLabel
+OpLoopMerge %11 %12 None
+OpBranch %13
+%13 = OpLabel
+OpKill
+%12 = OpLabel
+OpBranchConditional %false %10 %10
+%11 = OpLabel
+OpUnreachable
+OpFunctionEnd
+)";
+
+ SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ SinglePassRunAndCheck<AggressiveDCEPass>(text, text, false);
+}
} // namespace
} // namespace opt