Preserve OpenCL.DebugInfo.100 through elim-local-single-store (#3498)

This pass basically follows the same process as ssa-rewrite: it adds a DebugValue after each Store and removes the DebugDeclare or DebugValue Deref. It only does this if all instructions that are dependent on the Store are Loads and are replaced.
This commit is contained in:
greg-lunarg 2020-07-10 13:17:14 -06:00 committed by GitHub
parent a687057a83
commit cf8c86a2d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 383 additions and 12 deletions

View File

@ -374,6 +374,24 @@ bool DebugInfoManager::IsDebugDeclared(uint32_t variable_id) {
return dbg_decl_itr != var_id_to_dbg_decl_.end(); return dbg_decl_itr != var_id_to_dbg_decl_.end();
} }
void DebugInfoManager::KillDebugDeclares(uint32_t variable_id) {
bool done = false;
while (!done) {
Instruction* kill_inst = nullptr;
auto dbg_decl_itr = var_id_to_dbg_decl_.find(variable_id);
if (dbg_decl_itr != var_id_to_dbg_decl_.end()) {
for (auto dbg_decl : dbg_decl_itr->second) {
kill_inst = dbg_decl;
break;
}
}
if (kill_inst)
context()->KillInst(kill_inst);
else
done = true;
}
}
uint32_t DebugInfoManager::GetParentScope(uint32_t child_scope) { uint32_t DebugInfoManager::GetParentScope(uint32_t child_scope) {
auto dbg_scope_itr = id_to_dbg_inst_.find(child_scope); auto dbg_scope_itr = id_to_dbg_inst_.find(child_scope);
assert(dbg_scope_itr != id_to_dbg_inst_.end()); assert(dbg_scope_itr != id_to_dbg_inst_.end());
@ -485,6 +503,11 @@ void DebugInfoManager::AddDebugValue(Instruction* scope_and_line,
AnalyzeDebugInst(added_dbg_value); AnalyzeDebugInst(added_dbg_value);
if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse))
context()->get_def_use_mgr()->AnalyzeInstDefUse(added_dbg_value); context()->get_def_use_mgr()->AnalyzeInstDefUse(added_dbg_value);
if (context()->AreAnalysesValid(
IRContext::Analysis::kAnalysisInstrToBlockMapping)) {
auto insert_blk = context()->get_instr_block(insert_before);
context()->set_instr_block(added_dbg_value, insert_blk);
}
} }
} }

View File

@ -136,6 +136,9 @@ class DebugInfoManager {
// Return true if |variable_id| has DebugDeclare or DebugVal. // Return true if |variable_id| has DebugDeclare or DebugVal.
bool IsDebugDeclared(uint32_t variable_id); bool IsDebugDeclared(uint32_t variable_id);
// Kill all DebugDeclares for |variable_id|
void KillDebugDeclares(uint32_t variable_id);
// Generates a DebugValue instruction with value |value_id| for every local // Generates a DebugValue instruction with value |value_id| for every local
// variable that is in the scope of |scope_and_line| and whose memory is // variable that is in the scope of |scope_and_line| and whose memory is
// |variable_id| and inserts it after the instruction |insert_pos|. // |variable_id| and inserts it after the instruction |insert_pos|.

View File

@ -133,7 +133,27 @@ bool LocalSingleStoreElimPass::ProcessVariable(Instruction* var_inst) {
return false; return false;
} }
return RewriteLoads(store_inst, users); bool all_rewritten;
bool modified = RewriteLoads(store_inst, users, &all_rewritten);
// If all uses are rewritten and the variable has a DebugDeclare and the
// variable is not an aggregate, add a DebugValue after the store and remove
// the DebugDeclare.
uint32_t var_id = var_inst->result_id();
if (all_rewritten &&
context()->get_debug_info_mgr()->IsDebugDeclared(var_id)) {
const analysis::Type* var_type =
context()->get_type_mgr()->GetType(var_inst->type_id());
const analysis::Type* store_type = var_type->AsPointer()->pointee_type();
if (!(store_type->AsStruct() || store_type->AsArray())) {
context()->get_debug_info_mgr()->AddDebugValue(
store_inst, var_id, store_inst->GetSingleWordInOperand(1),
store_inst);
context()->get_debug_info_mgr()->KillDebugDeclares(var_id);
}
}
return modified;
} }
Instruction* LocalSingleStoreElimPass::FindSingleStoreAndCheckUses( Instruction* LocalSingleStoreElimPass::FindSingleStoreAndCheckUses(
@ -172,6 +192,14 @@ Instruction* LocalSingleStoreElimPass::FindSingleStoreAndCheckUses(
case SpvOpName: case SpvOpName:
case SpvOpCopyObject: case SpvOpCopyObject:
break; break;
case SpvOpExtInst: {
auto dbg_op = user->GetOpenCL100DebugOpcode();
if (dbg_op == OpenCLDebugInfo100DebugDeclare ||
dbg_op == OpenCLDebugInfo100DebugValue) {
break;
}
return nullptr;
}
default: default:
if (!user->IsDecoration()) { if (!user->IsDecoration()) {
// Don't know if this instruction modifies the variable. // Don't know if this instruction modifies the variable.
@ -218,7 +246,8 @@ bool LocalSingleStoreElimPass::FeedsAStore(Instruction* inst) const {
} }
bool LocalSingleStoreElimPass::RewriteLoads( bool LocalSingleStoreElimPass::RewriteLoads(
Instruction* store_inst, const std::vector<Instruction*>& uses) { Instruction* store_inst, const std::vector<Instruction*>& uses,
bool* all_rewritten) {
BasicBlock* store_block = context()->get_instr_block(store_inst); BasicBlock* store_block = context()->get_instr_block(store_inst);
DominatorAnalysis* dominator_analysis = DominatorAnalysis* dominator_analysis =
context()->GetDominatorAnalysis(store_block->GetParent()); context()->GetDominatorAnalysis(store_block->GetParent());
@ -229,16 +258,22 @@ bool LocalSingleStoreElimPass::RewriteLoads(
else else
stored_id = store_inst->GetSingleWordInOperand(kVariableInitIdInIdx); stored_id = store_inst->GetSingleWordInOperand(kVariableInitIdInIdx);
std::vector<Instruction*> uses_in_store_block; *all_rewritten = true;
bool modified = false; bool modified = false;
for (Instruction* use : uses) { for (Instruction* use : uses) {
if (use->opcode() == SpvOpLoad) { if (use->opcode() == SpvOpStore) continue;
if (dominator_analysis->Dominates(store_inst, use)) { auto dbg_op = use->GetOpenCL100DebugOpcode();
if (dbg_op == OpenCLDebugInfo100DebugDeclare ||
dbg_op == OpenCLDebugInfo100DebugValue)
continue;
if (use->opcode() == SpvOpLoad &&
dominator_analysis->Dominates(store_inst, use)) {
modified = true; modified = true;
context()->KillNamesAndDecorates(use->result_id()); context()->KillNamesAndDecorates(use->result_id());
context()->ReplaceAllUsesWith(use->result_id(), stored_id); context()->ReplaceAllUsesWith(use->result_id(), stored_id);
context()->KillInst(use); context()->KillInst(use);
} } else {
*all_rewritten = false;
} }
} }

View File

@ -89,9 +89,10 @@ class LocalSingleStoreElimPass : public Pass {
bool FeedsAStore(Instruction* inst) const; bool FeedsAStore(Instruction* inst) const;
// Replaces all of the loads in |uses| by the value stored in |store_inst|. // Replaces all of the loads in |uses| by the value stored in |store_inst|.
// The load instructions are then killed. // The load instructions are then killed. |all_rewritten| is true iff all
// uses have been rewritten.
bool RewriteLoads(Instruction* store_inst, bool RewriteLoads(Instruction* store_inst,
const std::vector<Instruction*>& uses); const std::vector<Instruction*>& uses, bool* all_rewritten);
// Extensions supported by this pass. // Extensions supported by this pass.
std::unordered_set<std::string> extensions_allowlist_; std::unordered_set<std::string> extensions_allowlist_;

View File

@ -902,6 +902,315 @@ TEST_F(LocalSingleStoreElimTest, VariablePointerTest) {
)"; )";
SinglePassRunAndMatch<LocalSingleStoreElimPass>(text, false); SinglePassRunAndMatch<LocalSingleStoreElimPass>(text, false);
} }
TEST_F(LocalSingleStoreElimTest, DebugDeclareTest) {
// If OpenCL.DebugInfo.100 enabled, check that store/load is still
// optimized, DebugValue placed after the store and the associated
// DebugDeclare is removed.
const std::string text = R"(
OpCapability Shader
%1 = OpExtInstImport "OpenCL.DebugInfo.100"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %g_sAniso %in_var_TEXCOORD2 %out_var_SV_Target0
OpExecutionMode %MainPs OriginUpperLeft
%20 = OpString "foo.frag"
%24 = OpString "PS_OUTPUT"
%28 = OpString "float"
%31 = OpString "vColor"
%33 = OpString "PS_INPUT"
%38 = OpString "vTextureCoords"
%40 = OpString "@type.2d.image"
%41 = OpString "type.2d.image"
%43 = OpString "Texture2D.TemplateParam"
%47 = OpString "src.MainPs"
%51 = OpString "tc"
%53 = OpString "ps_output"
%56 = OpString "i"
%58 = OpString "@type.sampler"
%59 = OpString "type.sampler"
%61 = OpString "g_sAniso"
%63 = 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_64 = OpConstant %uint 64
%65 = OpTypeFunction %void
%PS_INPUT = OpTypeStruct %v2float
%_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
%PS_OUTPUT = OpTypeStruct %v4float
%75 = 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
%39 = OpExtInst %void %1 DebugInfoNone
%55 = OpExtInst %void %1 DebugExpression
%22 = OpExtInst %void %1 DebugSource %20
%23 = OpExtInst %void %1 DebugCompilationUnit 1 4 %22 HLSL
%26 = OpExtInst %void %1 DebugTypeComposite %24 Structure %22 10 1 %23 %24 %uint_128 FlagIsProtected|FlagIsPrivate %27
%29 = OpExtInst %void %1 DebugTypeBasic %28 %uint_32 Float
%30 = OpExtInst %void %1 DebugTypeVector %29 4
%27 = OpExtInst %void %1 DebugTypeMember %31 %30 %22 12 5 %26 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
%35 = OpExtInst %void %1 DebugTypeComposite %33 Structure %22 5 1 %23 %33 %uint_64 FlagIsProtected|FlagIsPrivate %36
%37 = OpExtInst %void %1 DebugTypeVector %29 2
%36 = OpExtInst %void %1 DebugTypeMember %38 %37 %22 7 5 %35 %uint_0 %uint_64 FlagIsProtected|FlagIsPrivate
%42 = OpExtInst %void %1 DebugTypeComposite %40 Class %22 0 0 %23 %41 %39 FlagIsProtected|FlagIsPrivate
%44 = OpExtInst %void %1 DebugTypeTemplateParameter %43 %29 %39 %22 0 0
%45 = OpExtInst %void %1 DebugTypeTemplate %42 %44
%46 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %26 %35
%48 = OpExtInst %void %1 DebugFunction %47 %46 %22 15 1 %23 %47 FlagIsProtected|FlagIsPrivate 16 %39
%50 = OpExtInst %void %1 DebugLexicalBlock %22 16 1 %48
%52 = OpExtInst %void %1 DebugLocalVariable %51 %37 %22 19 12 %50 FlagIsLocal
%54 = OpExtInst %void %1 DebugLocalVariable %53 %26 %22 17 15 %50 FlagIsLocal
%57 = OpExtInst %void %1 DebugLocalVariable %56 %35 %22 15 29 %48 FlagIsLocal 1
%60 = OpExtInst %void %1 DebugTypeComposite %58 Structure %22 0 0 %23 %59 %39 FlagIsProtected|FlagIsPrivate
%62 = OpExtInst %void %1 DebugGlobalVariable %61 %60 %22 3 14 %23 %61 %g_sAniso FlagIsDefinition
%64 = OpExtInst %void %1 DebugGlobalVariable %63 %42 %22 1 11 %23 %63 %g_tColor FlagIsDefinition
%MainPs = OpFunction %void None %65
%66 = OpLabel
%114 = OpExtInst %void %1 DebugScope %50
%98 = OpVariable %_ptr_Function_PS_OUTPUT Function
%99 = OpVariable %_ptr_Function_v2float Function
%115 = OpExtInst %void %1 DebugNoScope
%100 = OpVariable %_ptr_Function_PS_OUTPUT Function
%param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
%70 = OpLoad %v2float %in_var_TEXCOORD2
%71 = OpCompositeConstruct %PS_INPUT %70
OpStore %param_var_i %71
%116 = OpExtInst %void %1 DebugScope %48
%102 = OpExtInst %void %1 DebugDeclare %57 %param_var_i %55
%117 = OpExtInst %void %1 DebugScope %50
%103 = OpExtInst %void %1 DebugDeclare %54 %98 %55
OpLine %20 19 17
%104 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_0
%105 = OpLoad %v2float %104
OpLine %20 19 12
OpStore %99 %105
%106 = OpExtInst %void %1 DebugDeclare %52 %99 %55
;CHECK-NOT: %106 = OpExtInst %void %1 DebugDeclare %52 %99 %55
;CHECK: %119 = OpExtInst %void %1 DebugValue %52 %105 %55
OpLine %20 20 26
%107 = OpLoad %type_2d_image %g_tColor
OpLine %20 20 46
%108 = OpLoad %type_sampler %g_sAniso
OpLine %20 20 57
%109 = OpLoad %v2float %99
;CHECK-NOT: %109 = OpLoad %v2float %99
OpLine %20 20 26
%110 = OpSampledImage %type_sampled_image %107 %108
%111 = OpImageSampleImplicitLod %v4float %110 %109 None
;CHECK-NOT: %111 = OpImageSampleImplicitLod %v4float %110 %109 None
;CHECK: %111 = OpImageSampleImplicitLod %v4float %110 %105 None
OpLine %20 20 5
%112 = OpAccessChain %_ptr_Function_v4float %98 %int_0
OpStore %112 %111
OpLine %20 21 12
%113 = OpLoad %PS_OUTPUT %98
OpLine %20 21 5
OpStore %100 %113
%118 = OpExtInst %void %1 DebugNoScope
%73 = OpLoad %PS_OUTPUT %100
%74 = OpCompositeExtract %v4float %73 0
OpStore %out_var_SV_Target0 %74
OpReturn
OpFunctionEnd
)";
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
SinglePassRunAndMatch<LocalSingleStoreElimPass>(text, false);
}
TEST_F(LocalSingleStoreElimTest, DebugValueTest) {
// If OpenCL.DebugInfo.100 enabled, check that store/load is still
// optimized, DebugValue placed after the store and the associated
// DebugValue Deref is removed.
const std::string text = R"(
OpCapability Shader
%1 = OpExtInstImport "OpenCL.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_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 Deref
%54 = OpExtInst %void %1 DebugExpression %53
%55 = OpExtInst %void %1 DebugSource %7
%56 = OpExtInst %void %1 DebugCompilationUnit 1 4 %55 HLSL
%57 = OpExtInst %void %1 DebugTypeComposite %8 Structure %55 10 1 %56 %8 %uint_128 FlagIsProtected|FlagIsPrivate %58
%59 = OpExtInst %void %1 DebugTypeBasic %9 %uint_32 Float
%60 = OpExtInst %void %1 DebugTypeVector %59 4
%58 = OpExtInst %void %1 DebugTypeMember %10 %60 %55 12 5 %57 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
%61 = OpExtInst %void %1 DebugTypeComposite %11 Structure %55 5 1 %56 %11 %uint_64 FlagIsProtected|FlagIsPrivate %62
%63 = OpExtInst %void %1 DebugTypeVector %59 2
%62 = OpExtInst %void %1 DebugTypeMember %12 %63 %55 7 5 %61 %uint_0 %uint_64 FlagIsProtected|FlagIsPrivate
%64 = OpExtInst %void %1 DebugTypeComposite %13 Class %55 0 0 %56 %14 %51 FlagIsProtected|FlagIsPrivate
%65 = OpExtInst %void %1 DebugTypeTemplateParameter %15 %59 %51 %55 0 0
%66 = OpExtInst %void %1 DebugTypeTemplate %64 %65
%67 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %57 %61
%68 = OpExtInst %void %1 DebugFunction %16 %67 %55 15 1 %56 %16 FlagIsProtected|FlagIsPrivate 16 %51
%69 = OpExtInst %void %1 DebugLexicalBlock %55 16 1 %68
%70 = OpExtInst %void %1 DebugLocalVariable %17 %63 %55 19 12 %69 FlagIsLocal
%71 = OpExtInst %void %1 DebugLocalVariable %18 %57 %55 17 15 %69 FlagIsLocal
%72 = OpExtInst %void %1 DebugLocalVariable %19 %61 %55 15 29 %68 FlagIsLocal 1
%73 = OpExtInst %void %1 DebugTypeComposite %20 Structure %55 0 0 %56 %21 %51 FlagIsProtected|FlagIsPrivate
%74 = OpExtInst %void %1 DebugGlobalVariable %22 %73 %55 3 14 %56 %22 %g_sAniso FlagIsDefinition
%75 = OpExtInst %void %1 DebugGlobalVariable %23 %64 %55 1 11 %56 %23 %g_tColor FlagIsDefinition
%MainPs = OpFunction %void None %45
%76 = OpLabel
%101 = OpExtInst %void %1 DebugScope %69
%78 = OpVariable %_ptr_Function_PS_OUTPUT Function
%79 = OpVariable %_ptr_Function_v2float Function
%102 = OpExtInst %void %1 DebugNoScope
%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
%103 = OpExtInst %void %1 DebugScope %68
%85 = OpExtInst %void %1 DebugDeclare %72 %param_var_i %52
%104 = OpExtInst %void %1 DebugScope %69
%87 = OpExtInst %void %1 DebugDeclare %71 %78 %52
OpLine %7 19 17
%88 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_0
%89 = OpLoad %v2float %88
OpLine %7 19 12
OpStore %79 %89
%90 = OpExtInst %void %1 DebugValue %70 %79 %54
;CHECK-NOT: %90 = OpExtInst %void %1 DebugValue %70 %79 %54
;CHECK: %106 = OpExtInst %void %1 DebugValue %70 %89 %52
OpLine %7 20 26
%91 = OpLoad %type_2d_image %g_tColor
OpLine %7 20 46
%92 = OpLoad %type_sampler %g_sAniso
OpLine %7 20 57
%93 = OpLoad %v2float %79
;CHECK-NOT: %93 = OpLoad %v2float %79
OpLine %7 20 26
%94 = OpSampledImage %type_sampled_image %91 %92
%95 = OpImageSampleImplicitLod %v4float %94 %93 None
;CHECK-NOT: %95 = OpImageSampleImplicitLod %v4float %94 %93 None
;CHECK: %95 = OpImageSampleImplicitLod %v4float %94 %89 None
OpLine %7 20 5
%96 = OpAccessChain %_ptr_Function_v4float %78 %int_0
OpStore %96 %95
OpLine %7 21 12
%97 = OpLoad %PS_OUTPUT %78
OpLine %7 21 5
OpStore %81 %97
%105 = OpExtInst %void %1 DebugNoScope
%99 = OpLoad %PS_OUTPUT %81
%100 = OpCompositeExtract %v4float %99 0
OpStore %out_var_SV_Target0 %100
OpReturn
OpFunctionEnd
)";
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
SinglePassRunAndMatch<LocalSingleStoreElimPass>(text, false);
}
// TODO(greg-lunarg): Add tests to verify handling of these cases: // TODO(greg-lunarg): Add tests to verify handling of these cases:
// //
// Other types // Other types