From 097ff25ea77a0b009efb2c1ff93f6decf154338d Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Fri, 12 Aug 2016 14:59:56 -0400 Subject: [PATCH] Allow OpUndef appearing in the type and global variable section. Also clean up API functions for adding instructions into the type and global values section. --- source/opt/ir_loader.cpp | 7 ++-- source/opt/module.h | 12 ++---- test/opt/test_ir_loader.cpp | 89 +++++++++++++++++++++++++++++++-------------- 3 files changed, 67 insertions(+), 41 deletions(-) diff --git a/source/opt/ir_loader.cpp b/source/opt/ir_loader.cpp index d1a50c1..01ffce4 100644 --- a/source/opt/ir_loader.cpp +++ b/source/opt/ir_loader.cpp @@ -85,10 +85,9 @@ void IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { module_->AddAnnotationInst(std::move(spv_inst)); } else if (IsTypeInst(opcode)) { module_->AddType(std::move(spv_inst)); - } else if (IsConstantInst(opcode)) { - module_->AddConstant(std::move(spv_inst)); - } else if (opcode == SpvOpVariable) { - module_->AddGlobalVariable(std::move(spv_inst)); + } else if (IsConstantInst(opcode) || opcode == SpvOpVariable || + opcode == SpvOpUndef) { + module_->AddGlobalValue(std::move(spv_inst)); } else { assert(0 && "unhandled inst type outside function defintion"); } diff --git a/source/opt/module.h b/source/opt/module.h index 5a487b7..1d6c98e 100644 --- a/source/opt/module.h +++ b/source/opt/module.h @@ -80,10 +80,8 @@ class Module { inline void AddAnnotationInst(std::unique_ptr a); // Appends a type-declaration instruction to this module. inline void AddType(std::unique_ptr t); - // Appends a constant-creation instruction to this module. - inline void AddConstant(std::unique_ptr c); - // Appends a global variable-declaration instruction to this module. - inline void AddGlobalVariable(std::unique_ptr v); + // Appends a constant, global variable, or OpUndef instruction to this module. + inline void AddGlobalValue(std::unique_ptr v); // Appends a function to this module. inline void AddFunction(std::unique_ptr f); @@ -184,11 +182,7 @@ inline void Module::AddType(std::unique_ptr t) { types_values_.emplace_back(std::move(t)); } -inline void Module::AddConstant(std::unique_ptr c) { - types_values_.emplace_back(std::move(c)); -} - -inline void Module::AddGlobalVariable(std::unique_ptr v) { +inline void Module::AddGlobalValue(std::unique_ptr v) { types_values_.emplace_back(std::move(v)); } diff --git a/test/opt/test_ir_loader.cpp b/test/opt/test_ir_loader.cpp index c5ccd5e..7d4cca0 100644 --- a/test/opt/test_ir_loader.cpp +++ b/test/opt/test_ir_loader.cpp @@ -32,11 +32,24 @@ namespace { using namespace spvtools; +void DoRoundTripCheck(const std::string& text) { + SpvTools t(SPV_ENV_UNIVERSAL_1_1); + std::unique_ptr module = t.BuildModule(text); + ASSERT_NE(nullptr, module); + + std::vector binary; + module->ToBinary(&binary, /* skip_nop = */ false); + + std::string disassembled_text; + EXPECT_EQ(SPV_SUCCESS, t.Disassemble(binary, &disassembled_text)); + EXPECT_EQ(text, disassembled_text); +} + TEST(IrBuilder, RoundTrip) { // #version 310 es // int add(int a, int b) { return a + b; } // void main() { add(1, 2); } - const std::string text = + DoRoundTripCheck( // clang-format off "OpCapability Shader\n" "%1 = OpExtInstImport \"GLSL.std.450\"\n" @@ -75,25 +88,14 @@ TEST(IrBuilder, RoundTrip) { "%19 = OpLoad %int %b\n" "%20 = OpIAdd %int %18 %19\n" "OpReturnValue %20\n" - "OpFunctionEnd\n"; + "OpFunctionEnd\n"); // clang-format on - - SpvTools t(SPV_ENV_UNIVERSAL_1_1); - std::unique_ptr module = t.BuildModule(text); - ASSERT_NE(nullptr, module); - - std::vector binary; - module->ToBinary(&binary, /* skip_nop = */ false); - - std::string disassembled_text; - EXPECT_EQ(SPV_SUCCESS, t.Disassemble(binary, &disassembled_text)); - EXPECT_EQ(text, disassembled_text); } TEST(IrBuilder, KeepLineDebugInfo) { // #version 310 es // void main() {} - const std::string text = + DoRoundTripCheck( // clang-format off "OpCapability Shader\n" "%1 = OpExtInstImport \"GLSL.std.450\"\n" @@ -115,19 +117,8 @@ TEST(IrBuilder, KeepLineDebugInfo) { "OpLine %3 4 4\n" "OpNoLine\n" "OpReturn\n" - "OpFunctionEnd\n"; + "OpFunctionEnd\n"); // clang-format on - - SpvTools t(SPV_ENV_UNIVERSAL_1_1); - std::unique_ptr module = t.BuildModule(text); - ASSERT_NE(nullptr, module); - - std::vector binary; - module->ToBinary(&binary, /* skip_nop = */ false); - - std::string disassembled_text; - EXPECT_EQ(SPV_SUCCESS, t.Disassemble(binary, &disassembled_text)); - EXPECT_EQ(text, disassembled_text); } TEST(IrBuilder, LocalGlobalVariables) { @@ -145,7 +136,7 @@ TEST(IrBuilder, LocalGlobalVariables) { // void main() { // float lv1 = gv1 - gv2; // } - const std::string text = + DoRoundTripCheck( // clang-format off "OpCapability Shader\n" "%1 = OpExtInstImport \"GLSL.std.450\"\n" @@ -196,13 +187,37 @@ TEST(IrBuilder, LocalGlobalVariables) { "%29 = OpLoad %float %lv2\n" "%30 = OpFDiv %float %28 %29\n" "OpReturnValue %30\n" - "OpFunctionEnd\n"; + "OpFunctionEnd\n"); + // clang-format on +} + +TEST(IrBuilder, OpUndefOutsideFunction) { + // #version 310 es + // void main() {} + const std::string text = + // clang-format off + "OpMemoryModel Logical GLSL450\n" + "%int = OpTypeInt 32 1\n" + "%uint = OpTypeInt 32 0\n" + "%float = OpTypeFloat 32\n" + "%4 = OpUndef %int\n" + "%5 = OpConstant %int 10\n" + "%6 = OpUndef %uint\n" + "%bool = OpTypeBool\n" + "%8 = OpUndef %float\n" + "%double = OpTypeFloat 64\n"; // clang-format on SpvTools t(SPV_ENV_UNIVERSAL_1_1); std::unique_ptr module = t.BuildModule(text); ASSERT_NE(nullptr, module); + int opundef_count = 0; + for (const auto& inst : module->types_values()) { + if (inst.opcode() == SpvOpUndef) ++opundef_count; + } + EXPECT_EQ(3, opundef_count); + std::vector binary; module->ToBinary(&binary, /* skip_nop = */ false); @@ -211,4 +226,22 @@ TEST(IrBuilder, LocalGlobalVariables) { EXPECT_EQ(text, disassembled_text); } +TEST(IrBuilder, OpUndefInBasicBlock) { + DoRoundTripCheck( + // clang-format off + "OpMemoryModel Logical GLSL450\n" + "OpName %main \"main\"\n" + "%void = OpTypeVoid\n" + "%uint = OpTypeInt 32 0\n" + "%double = OpTypeFloat 64\n" + "%5 = OpTypeFunction %void\n" + "%main = OpFunction %void None %5\n" + "%6 = OpLabel\n" + "%7 = OpUndef %uint\n" + "%8 = OpUndef %double\n" + "OpReturn\n" + "OpFunctionEnd\n"); + // clang-format on +} + } // anonymous namespace -- 2.7.4