mirror of
https://gitee.com/openharmony/third_party_spirv-tools
synced 2024-11-27 09:32:08 +00:00
spirv-opt: properly preserve DebugValue indexes operand (#4022)
spirv-opt has a bug that `DebugInfoManager::AddDebugValueWithIndex()` does not preserve `Indexes` operands of [DebugValue](https://www.khronos.org/registry/spir-v/specs/unified1/OpenCL.DebugInfo.100.html#DebugValue). It has to preserve all of those `Indexes` operands, but it preserves only the first index operand. This PR removes `DebugInfoManager::AddDebugValueWithIndex()` and lets the spirv-opt use `DebugInfoManager::AddDebugValueForDecl()`. `DebugInfoManager::AddDebugValueForDecl()` preserves the Indexes operand correctly.
This commit is contained in:
parent
1cda495274
commit
f686518cee
@ -31,9 +31,7 @@ static const uint32_t kDebugInlinedAtOperandInlinedIndex = 6;
|
||||
static const uint32_t kDebugExpressOperandOperationIndex = 4;
|
||||
static const uint32_t kDebugDeclareOperandLocalVariableIndex = 4;
|
||||
static const uint32_t kDebugDeclareOperandVariableIndex = 5;
|
||||
static const uint32_t kDebugValueOperandLocalVariableIndex = 4;
|
||||
static const uint32_t kDebugValueOperandExpressionIndex = 6;
|
||||
static const uint32_t kDebugValueOperandIndexesIndex = 7;
|
||||
static const uint32_t kDebugOperationOperandOperationIndex = 4;
|
||||
static const uint32_t kOpVariableOperandStorageClassIndex = 2;
|
||||
static const uint32_t kDebugLocalVariableOperandParentIndex = 9;
|
||||
@ -479,44 +477,6 @@ bool DebugInfoManager::IsDeclareVisibleToInstr(Instruction* dbg_declare,
|
||||
return false;
|
||||
}
|
||||
|
||||
Instruction* DebugInfoManager::AddDebugValueWithIndex(
|
||||
uint32_t dbg_local_var_id, uint32_t value_id, uint32_t expr_id,
|
||||
uint32_t index_id, Instruction* insert_before) {
|
||||
uint32_t result_id = context()->TakeNextId();
|
||||
if (!result_id) return nullptr;
|
||||
std::unique_ptr<Instruction> new_dbg_value(new Instruction(
|
||||
context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(),
|
||||
result_id,
|
||||
{
|
||||
{spv_operand_type_t::SPV_OPERAND_TYPE_ID,
|
||||
{context()
|
||||
->get_feature_mgr()
|
||||
->GetExtInstImportId_OpenCL100DebugInfo()}},
|
||||
{spv_operand_type_t::SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
|
||||
{static_cast<uint32_t>(OpenCLDebugInfo100DebugValue)}},
|
||||
{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {dbg_local_var_id}},
|
||||
{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {value_id}},
|
||||
{spv_operand_type_t::SPV_OPERAND_TYPE_ID,
|
||||
{expr_id == 0 ? GetEmptyDebugExpression()->result_id() : expr_id}},
|
||||
}));
|
||||
if (index_id) {
|
||||
new_dbg_value->AddOperand(
|
||||
{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {index_id}});
|
||||
}
|
||||
|
||||
Instruction* added_dbg_value =
|
||||
insert_before->InsertBefore(std::move(new_dbg_value));
|
||||
AnalyzeDebugInst(added_dbg_value);
|
||||
if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse))
|
||||
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);
|
||||
}
|
||||
return added_dbg_value;
|
||||
}
|
||||
|
||||
bool DebugInfoManager::AddDebugValueIfVarDeclIsVisible(
|
||||
Instruction* scope_and_line, uint32_t variable_id, uint32_t value_id,
|
||||
Instruction* insert_pos,
|
||||
@ -540,28 +500,15 @@ bool DebugInfoManager::AddDebugValueIfVarDeclIsVisible(
|
||||
insert_before->opcode() == SpvOpVariable) {
|
||||
insert_before = insert_before->NextNode();
|
||||
}
|
||||
|
||||
uint32_t index_id = 0;
|
||||
if (dbg_decl_or_val->NumOperands() > kDebugValueOperandIndexesIndex) {
|
||||
index_id =
|
||||
dbg_decl_or_val->GetSingleWordOperand(kDebugValueOperandIndexesIndex);
|
||||
}
|
||||
|
||||
Instruction* added_dbg_value =
|
||||
AddDebugValueWithIndex(dbg_decl_or_val->GetSingleWordOperand(
|
||||
kDebugValueOperandLocalVariableIndex),
|
||||
value_id, 0, index_id, insert_before);
|
||||
assert(added_dbg_value != nullptr);
|
||||
added_dbg_value->UpdateDebugInfoFrom(scope_and_line);
|
||||
AnalyzeDebugInst(added_dbg_value);
|
||||
modified = true;
|
||||
modified |= AddDebugValueForDecl(dbg_decl_or_val, value_id,
|
||||
insert_before) != nullptr;
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
bool DebugInfoManager::AddDebugValueForDecl(Instruction* dbg_decl,
|
||||
uint32_t value_id) {
|
||||
if (dbg_decl == nullptr || !IsDebugDeclare(dbg_decl)) return false;
|
||||
Instruction* DebugInfoManager::AddDebugValueForDecl(
|
||||
Instruction* dbg_decl, uint32_t value_id, Instruction* insert_before) {
|
||||
if (dbg_decl == nullptr || !IsDebugDeclare(dbg_decl)) return nullptr;
|
||||
|
||||
std::unique_ptr<Instruction> dbg_val(dbg_decl->Clone(context()));
|
||||
dbg_val->SetResultId(context()->TakeNextId());
|
||||
@ -571,16 +518,16 @@ bool DebugInfoManager::AddDebugValueForDecl(Instruction* dbg_decl,
|
||||
dbg_val->SetOperand(kDebugValueOperandExpressionIndex,
|
||||
{GetEmptyDebugExpression()->result_id()});
|
||||
|
||||
auto* added_dbg_val = dbg_decl->InsertBefore(std::move(dbg_val));
|
||||
auto* added_dbg_val = insert_before->InsertBefore(std::move(dbg_val));
|
||||
AnalyzeDebugInst(added_dbg_val);
|
||||
if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse))
|
||||
context()->get_def_use_mgr()->AnalyzeInstDefUse(added_dbg_val);
|
||||
if (context()->AreAnalysesValid(
|
||||
IRContext::Analysis::kAnalysisInstrToBlockMapping)) {
|
||||
auto insert_blk = context()->get_instr_block(dbg_decl);
|
||||
auto insert_blk = context()->get_instr_block(insert_before);
|
||||
context()->set_instr_block(added_dbg_val, insert_blk);
|
||||
}
|
||||
return true;
|
||||
return added_dbg_val;
|
||||
}
|
||||
|
||||
uint32_t DebugInfoManager::GetVariableIdOfDebugValueUsedForDeclare(
|
||||
|
@ -151,18 +151,13 @@ class DebugInfoManager {
|
||||
Instruction* insert_pos,
|
||||
std::unordered_set<Instruction*>* invisible_decls);
|
||||
|
||||
// Generates a DebugValue instruction with |dbg_local_var_id|, |value_id|,
|
||||
// |expr_id|, |index_id| operands and inserts it before |insert_before|.
|
||||
Instruction* AddDebugValueWithIndex(uint32_t dbg_local_var_id,
|
||||
uint32_t value_id, uint32_t expr_id,
|
||||
uint32_t index_id,
|
||||
// Creates a DebugValue for DebugDeclare |dbg_decl| and inserts it before
|
||||
// |insert_before|. The new DebugValue has the same line, scope, and
|
||||
// operands with DebugDeclare but it uses |value_id| for value. Returns
|
||||
// the added DebugValue, or nullptr if it does not add a DebugValue.
|
||||
Instruction* AddDebugValueForDecl(Instruction* dbg_decl, uint32_t value_id,
|
||||
Instruction* insert_before);
|
||||
|
||||
// Adds DebugValue for DebugDeclare |dbg_decl|. The new DebugValue has the
|
||||
// same line, scope, and operands but it uses |value_id| for value. Returns
|
||||
// weather it succeeds or not.
|
||||
bool AddDebugValueForDecl(Instruction* dbg_decl, uint32_t value_id);
|
||||
|
||||
// Erases |instr| from data structures of this class.
|
||||
void ClearDebugInfo(Instruction* instr);
|
||||
|
||||
|
@ -174,7 +174,8 @@ bool LocalSingleStoreElimPass::RewriteDebugDeclares(Instruction* store_inst,
|
||||
context()->GetDominatorAnalysis(store_block->GetParent());
|
||||
for (auto* decl : invisible_decls) {
|
||||
if (dominator_analysis->Dominates(store_inst, decl)) {
|
||||
context()->get_debug_info_mgr()->AddDebugValueForDecl(decl, value_id);
|
||||
context()->get_debug_info_mgr()->AddDebugValueForDecl(decl, value_id,
|
||||
decl);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "source/opt/types.h"
|
||||
#include "source/util/make_unique.h"
|
||||
|
||||
static const uint32_t kDebugDeclareOperandLocalVariableIndex = 4;
|
||||
static const uint32_t kDebugValueOperandValueIndex = 5;
|
||||
static const uint32_t kDebugValueOperandExpressionIndex = 6;
|
||||
|
||||
@ -173,17 +172,19 @@ bool ScalarReplacementPass::ReplaceWholeDebugDeclare(
|
||||
// Add DebugValue instruction with Indexes operand and Deref operation.
|
||||
int32_t idx = 0;
|
||||
for (const auto* var : replacements) {
|
||||
uint32_t dbg_local_variable =
|
||||
dbg_decl->GetSingleWordOperand(kDebugDeclareOperandLocalVariableIndex);
|
||||
uint32_t index_id = context()->get_constant_mgr()->GetSIntConst(idx);
|
||||
|
||||
Instruction* added_dbg_value =
|
||||
context()->get_debug_info_mgr()->AddDebugValueWithIndex(
|
||||
dbg_local_variable,
|
||||
/*value_id=*/var->result_id(), /*expr_id=*/deref_expr->result_id(),
|
||||
index_id, /*insert_before=*/var->NextNode());
|
||||
context()->get_debug_info_mgr()->AddDebugValueForDecl(
|
||||
dbg_decl, /*value_id=*/var->result_id(),
|
||||
/*insert_before=*/var->NextNode());
|
||||
if (added_dbg_value == nullptr) return false;
|
||||
added_dbg_value->UpdateDebugInfoFrom(dbg_decl);
|
||||
added_dbg_value->AddOperand(
|
||||
{SPV_OPERAND_TYPE_ID,
|
||||
{context()->get_constant_mgr()->GetSIntConst(idx)}});
|
||||
added_dbg_value->SetOperand(kDebugValueOperandExpressionIndex,
|
||||
{deref_expr->result_id()});
|
||||
if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse)) {
|
||||
context()->get_def_use_mgr()->AnalyzeInstUse(added_dbg_value);
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
return true;
|
||||
|
@ -680,8 +680,8 @@ Pass::Status SSARewriter::AddDebugValuesForInvisibleDebugDecls(Function* fp) {
|
||||
// If |value| dominates |decl|, we can set it as DebugValue.
|
||||
if (value && (pass_->context()->get_instr_block(value) == nullptr ||
|
||||
dom_tree->Dominates(value, decl))) {
|
||||
if (!pass_->context()->get_debug_info_mgr()->AddDebugValueForDecl(
|
||||
decl, value->result_id())) {
|
||||
if (pass_->context()->get_debug_info_mgr()->AddDebugValueForDecl(
|
||||
decl, value->result_id(), decl) == nullptr) {
|
||||
return Pass::Status::Failure;
|
||||
}
|
||||
} else {
|
||||
@ -689,8 +689,8 @@ Pass::Status SSARewriter::AddDebugValuesForInvisibleDebugDecls(Function* fp) {
|
||||
// assign the value in the immediate dominator.
|
||||
value_id = GetValueAtBlock(var_id, dom_tree->ImmediateDominator(bb));
|
||||
if (value_id &&
|
||||
!pass_->context()->get_debug_info_mgr()->AddDebugValueForDecl(
|
||||
decl, value_id)) {
|
||||
pass_->context()->get_debug_info_mgr()->AddDebugValueForDecl(
|
||||
decl, value_id, decl) == nullptr) {
|
||||
return Pass::Status::Failure;
|
||||
}
|
||||
}
|
||||
|
@ -2371,6 +2371,154 @@ TEST_F(LocalSSAElimTest, AddDebugValueForFunctionParameterWithPhi) {
|
||||
SinglePassRunAndMatch<SSARewritePass>(text, true);
|
||||
}
|
||||
|
||||
TEST_F(LocalSSAElimTest, DebugValueWithIndexesInForLoop) {
|
||||
// #version 140
|
||||
//
|
||||
// in vec4 BC;
|
||||
// out float fo;
|
||||
//
|
||||
// struct T {
|
||||
// float a;
|
||||
// float f;
|
||||
// };
|
||||
//
|
||||
// struct value {
|
||||
// int x;
|
||||
// int y;
|
||||
// T z;
|
||||
// };
|
||||
//
|
||||
// void main()
|
||||
// {
|
||||
// value v;
|
||||
// v.z.f = 0.0;
|
||||
// for (int i=0; i<4; i++) {
|
||||
// v.z.f = v.z.f + BC[i];
|
||||
// }
|
||||
// fo = v.z.f;
|
||||
// }
|
||||
|
||||
const std::string text = R"(
|
||||
; CHECK: [[f_name:%\w+]] = OpString "f"
|
||||
; CHECK: [[dbg_f:%\w+]] = OpExtInst %void [[ext:%\d+]] DebugLocalVariable [[f_name]]
|
||||
|
||||
; CHECK: OpStore %f %float_0
|
||||
; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_f]] %float_0 [[null_expr:%\d+]] %int_2 %int_1
|
||||
|
||||
; CHECK-NOT: DebugDeclare
|
||||
|
||||
; CHECK: [[loop_head:%\w+]] = OpLabel
|
||||
; CHECK: [[phi0:%\w+]] = OpPhi %float %float_0
|
||||
; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[phi0]] [[null_expr]] %int_2 %int_1
|
||||
; CHECK: OpLoopMerge [[loop_merge:%\w+]] [[loop_cont:%\w+]] None
|
||||
; CHECK-NEXT: OpBranch [[loop_body:%\w+]]
|
||||
|
||||
; CHECK-NEXT: [[loop_body]] = OpLabel
|
||||
; CHECK: OpBranchConditional {{%\w+}} [[bb:%\w+]] [[loop_merge]]
|
||||
|
||||
; CHECK: [[bb]] = OpLabel
|
||||
; CHECK: OpStore %f [[f_val:%\w+]]
|
||||
; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[f_val]] [[null_expr]] %int_2 %int_1
|
||||
; CHECK-NEXT: OpBranch [[loop_cont]]
|
||||
|
||||
; CHECK: [[loop_cont]] = OpLabel
|
||||
; CHECK: OpBranch [[loop_head]]
|
||||
|
||||
; CHECK: [[loop_merge]] = OpLabel
|
||||
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
%ext = OpExtInstImport "OpenCL.DebugInfo.100"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main" %BC %fo
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
%file_name = OpString "test"
|
||||
OpSource GLSL 140
|
||||
%float_name = OpString "float"
|
||||
%main_name = OpString "main"
|
||||
%f_name = OpString "f"
|
||||
%i_name = OpString "i"
|
||||
OpName %main "main"
|
||||
OpName %f "f"
|
||||
OpName %i "i"
|
||||
OpName %BC "BC"
|
||||
OpName %fo "fo"
|
||||
%void = OpTypeVoid
|
||||
%8 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%_ptr_Function_float = OpTypePointer Function %float
|
||||
%float_0 = OpConstant %float 0
|
||||
%int = OpTypeInt 32 1
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_32 = OpConstant %uint 32
|
||||
%_ptr_Function_int = OpTypePointer Function %int
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_4 = OpConstant %int 4
|
||||
%bool = OpTypeBool
|
||||
%v4float = OpTypeVector %float 4
|
||||
%_ptr_Input_v4float = OpTypePointer Input %v4float
|
||||
%BC = OpVariable %_ptr_Input_v4float Input
|
||||
%_ptr_Input_float = OpTypePointer Input %float
|
||||
%int_1 = OpConstant %int 1
|
||||
%int_2 = OpConstant %int 2
|
||||
%_ptr_Output_float = OpTypePointer Output %float
|
||||
%fo = OpVariable %_ptr_Output_float Output
|
||||
%deref = OpExtInst %void %ext DebugOperation Deref
|
||||
%null_expr = OpExtInst %void %ext DebugExpression
|
||||
%deref_expr = OpExtInst %void %ext DebugExpression %deref
|
||||
%src = OpExtInst %void %ext DebugSource %file_name
|
||||
%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
|
||||
%dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
|
||||
%dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_tf 4
|
||||
%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f
|
||||
%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
|
||||
%dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_v4f %src 0 0 %dbg_main FlagIsLocal
|
||||
%dbg_i = OpExtInst %void %ext DebugLocalVariable %i_name %dbg_v4f %src 0 0 %dbg_main FlagIsLocal
|
||||
%main = OpFunction %void None %8
|
||||
%22 = OpLabel
|
||||
%s0 = OpExtInst %void %ext DebugScope %dbg_main
|
||||
%f = OpVariable %_ptr_Function_float Function
|
||||
%i = OpVariable %_ptr_Function_int Function
|
||||
OpStore %f %float_0
|
||||
OpStore %i %int_0
|
||||
%decl0 = OpExtInst %void %ext DebugValue %dbg_f %f %deref_expr %int_2 %int_1
|
||||
%decl1 = OpExtInst %void %ext DebugDeclare %dbg_i %i %null_expr
|
||||
OpBranch %23
|
||||
%23 = OpLabel
|
||||
%s1 = OpExtInst %void %ext DebugScope %dbg_main
|
||||
OpLoopMerge %24 %25 None
|
||||
OpBranch %26
|
||||
%26 = OpLabel
|
||||
%s2 = OpExtInst %void %ext DebugScope %dbg_main
|
||||
%27 = OpLoad %int %i
|
||||
%28 = OpSLessThan %bool %27 %int_4
|
||||
OpBranchConditional %28 %29 %24
|
||||
%29 = OpLabel
|
||||
%s3 = OpExtInst %void %ext DebugScope %dbg_main
|
||||
%30 = OpLoad %float %f
|
||||
%31 = OpLoad %int %i
|
||||
%32 = OpAccessChain %_ptr_Input_float %BC %31
|
||||
%33 = OpLoad %float %32
|
||||
%34 = OpFAdd %float %30 %33
|
||||
OpStore %f %34
|
||||
OpBranch %25
|
||||
%25 = OpLabel
|
||||
%s4 = OpExtInst %void %ext DebugScope %dbg_main
|
||||
%35 = OpLoad %int %i
|
||||
%36 = OpIAdd %int %35 %int_1
|
||||
OpStore %i %36
|
||||
OpBranch %23
|
||||
%24 = OpLabel
|
||||
%s5 = OpExtInst %void %ext DebugScope %dbg_main
|
||||
%37 = OpLoad %float %f
|
||||
OpStore %fo %37
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndMatch<SSARewritePass>(text, true);
|
||||
}
|
||||
|
||||
TEST_F(LocalSSAElimTest, PartiallyKillDebugDeclare) {
|
||||
// For a reference variable e.g., int i in the following example,
|
||||
// we do not propagate DebugValue for a store or phi instruction
|
||||
|
@ -2079,6 +2079,124 @@ OpFunctionEnd
|
||||
SinglePassRunAndMatch<ScalarReplacementPass>(text, true);
|
||||
}
|
||||
|
||||
TEST_F(ScalarReplacementTest, DebugValueWithIndex) {
|
||||
const std::string text = R"(
|
||||
OpCapability Shader
|
||||
OpCapability Linkage
|
||||
%ext = OpExtInstImport "OpenCL.DebugInfo.100"
|
||||
OpMemoryModel Logical GLSL450
|
||||
%test = OpString "test"
|
||||
OpName %6 "simple_struct"
|
||||
%1 = OpTypeVoid
|
||||
%2 = OpTypeInt 32 0
|
||||
%uint_32 = OpConstant %2 32
|
||||
%3 = OpTypeStruct %2 %2 %2 %2
|
||||
%4 = OpTypePointer Function %3
|
||||
%5 = OpTypePointer Function %2
|
||||
%6 = OpTypeFunction %2
|
||||
%7 = OpConstantNull %3
|
||||
%8 = OpConstant %2 0
|
||||
%9 = OpConstant %2 1
|
||||
%10 = OpConstant %2 2
|
||||
%11 = OpConstant %2 3
|
||||
%deref = OpExtInst %1 %ext DebugOperation Deref
|
||||
%deref_expr = OpExtInst %1 %ext DebugExpression %deref
|
||||
%null_expr = OpExtInst %1 %ext DebugExpression
|
||||
%src = OpExtInst %1 %ext DebugSource %test
|
||||
%cu = OpExtInst %1 %ext DebugCompilationUnit 1 4 %src HLSL
|
||||
%dbg_tf = OpExtInst %1 %ext DebugTypeBasic %test %uint_32 Float
|
||||
%main_ty = OpExtInst %1 %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %1
|
||||
%dbg_main = OpExtInst %1 %ext DebugFunction %test %main_ty %src 0 0 %cu %test FlagIsProtected|FlagIsPrivate 0 %12
|
||||
%dbg_foo = OpExtInst %1 %ext DebugLocalVariable %test %dbg_tf %src 0 0 %dbg_main FlagIsLocal
|
||||
%12 = OpFunction %2 None %6
|
||||
%13 = OpLabel
|
||||
%scope = OpExtInst %1 %ext DebugScope %dbg_main
|
||||
%14 = OpVariable %4 Function %7
|
||||
|
||||
; CHECK: [[deref:%\w+]] = OpExtInst %void [[ext:%\w+]] DebugOperation Deref
|
||||
; CHECK: [[deref_expr:%\w+]] = OpExtInst %void [[ext]] DebugExpression [[deref]]
|
||||
; CHECK: [[dbg_local_var:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable
|
||||
; CHECK: [[repl3:%\w+]] = OpVariable %_ptr_Function_uint Function
|
||||
; CHECK: [[repl2:%\w+]] = OpVariable %_ptr_Function_uint Function
|
||||
; CHECK: [[repl1:%\w+]] = OpVariable %_ptr_Function_uint Function
|
||||
; CHECK: [[repl0:%\w+]] = OpVariable %_ptr_Function_uint Function
|
||||
; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl0]] [[deref_expr]] %uint_0 %uint_1 %uint_2 %int_0
|
||||
; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl1]] [[deref_expr]] %uint_0 %uint_1 %uint_2 %int_1
|
||||
; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl2]] [[deref_expr]] %uint_0 %uint_1 %uint_2 %int_2
|
||||
; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl3]] [[deref_expr]] %uint_0 %uint_1 %uint_2 %int_3
|
||||
%value = OpExtInst %1 %ext DebugValue %dbg_foo %14 %deref_expr %8 %9 %10
|
||||
|
||||
%15 = OpInBoundsAccessChain %5 %14 %8
|
||||
%16 = OpLoad %2 %15
|
||||
%17 = OpAccessChain %5 %14 %10
|
||||
%18 = OpLoad %2 %17
|
||||
%19 = OpIAdd %2 %16 %18
|
||||
OpReturnValue %19
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndMatch<ScalarReplacementPass>(text, true);
|
||||
}
|
||||
|
||||
TEST_F(ScalarReplacementTest, DebugDeclareForVariableInOtherBB) {
|
||||
const std::string text = R"(
|
||||
OpCapability Shader
|
||||
OpCapability Linkage
|
||||
%ext = OpExtInstImport "OpenCL.DebugInfo.100"
|
||||
OpMemoryModel Logical GLSL450
|
||||
%test = OpString "test"
|
||||
OpName %6 "simple_struct"
|
||||
%1 = OpTypeVoid
|
||||
%2 = OpTypeInt 32 0
|
||||
%uint_32 = OpConstant %2 32
|
||||
%3 = OpTypeStruct %2 %2 %2 %2
|
||||
%4 = OpTypePointer Function %3
|
||||
%5 = OpTypePointer Function %2
|
||||
%6 = OpTypeFunction %2
|
||||
%7 = OpConstantNull %3
|
||||
%8 = OpConstant %2 0
|
||||
%9 = OpConstant %2 1
|
||||
%10 = OpConstant %2 2
|
||||
%11 = OpConstant %2 3
|
||||
%deref = OpExtInst %1 %ext DebugOperation Deref
|
||||
%deref_expr = OpExtInst %1 %ext DebugExpression %deref
|
||||
%null_expr = OpExtInst %1 %ext DebugExpression
|
||||
%src = OpExtInst %1 %ext DebugSource %test
|
||||
%cu = OpExtInst %1 %ext DebugCompilationUnit 1 4 %src HLSL
|
||||
%dbg_tf = OpExtInst %1 %ext DebugTypeBasic %test %uint_32 Float
|
||||
%main_ty = OpExtInst %1 %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %1
|
||||
%dbg_main = OpExtInst %1 %ext DebugFunction %test %main_ty %src 0 0 %cu %test FlagIsProtected|FlagIsPrivate 0 %12
|
||||
%dbg_foo = OpExtInst %1 %ext DebugLocalVariable %test %dbg_tf %src 0 0 %dbg_main FlagIsLocal
|
||||
%12 = OpFunction %2 None %6
|
||||
%13 = OpLabel
|
||||
%scope = OpExtInst %1 %ext DebugScope %dbg_main
|
||||
%14 = OpVariable %4 Function %7
|
||||
|
||||
; CHECK: [[dbg_local_var:%\w+]] = OpExtInst %void [[ext:%\w+]] DebugLocalVariable
|
||||
; CHECK: [[repl3:%\w+]] = OpVariable %_ptr_Function_uint Function
|
||||
; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl3]] [[deref_expr:%\w+]] %int_3
|
||||
; CHECK: [[repl2:%\w+]] = OpVariable %_ptr_Function_uint Function
|
||||
; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl2]] [[deref_expr]] %int_2
|
||||
; CHECK: [[repl1:%\w+]] = OpVariable %_ptr_Function_uint Function
|
||||
; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl1]] [[deref_expr]] %int_1
|
||||
; CHECK: [[repl0:%\w+]] = OpVariable %_ptr_Function_uint Function
|
||||
; CHECK: OpExtInst %void [[ext]] DebugValue [[dbg_local_var]] [[repl0]] [[deref_expr]] %int_0
|
||||
|
||||
OpBranch %20
|
||||
%20 = OpLabel
|
||||
%value = OpExtInst %1 %ext DebugDeclare %dbg_foo %14 %null_expr
|
||||
%15 = OpInBoundsAccessChain %5 %14 %8
|
||||
%16 = OpLoad %2 %15
|
||||
%17 = OpAccessChain %5 %14 %10
|
||||
%18 = OpLoad %2 %17
|
||||
%19 = OpIAdd %2 %16 %18
|
||||
OpReturnValue %19
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndMatch<ScalarReplacementPass>(text, true);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
||||
|
Loading…
Reference in New Issue
Block a user