From e537b8b48840be891c12d7ab8c7c4f3b98eefde5 Mon Sep 17 00:00:00 2001 From: Dejan Mircevski Date: Sun, 10 Jan 2016 19:37:00 -0500 Subject: [PATCH] Fix unreachable-block removal. Add a test for loop without a condition. Change-Id: Idd7fc462218a84b1e745207e2975a3f2897d30a0 --- SPIRV/GlslangToSpv.cpp | 4 +-- SPIRV/SpvBuilder.cpp | 2 +- SPIRV/spvIR.h | 9 +++++- Test/baseResults/spv.for-notest.vert.out | 50 ++++++++++++++++++++++++++++++++ Test/spv.for-notest.vert | 6 ++++ 5 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 Test/baseResults/spv.for-notest.vert.out create mode 100644 Test/spv.for-notest.vert diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 769cf50..06ab094 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -1356,7 +1356,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn builder.setBuildPoint(&blocks.body); if (node->getBody()) - node->getBody()->traverse(this); // continue->cont, break->exit + node->getBody()->traverse(this); builder.createBranch(&blocks.continue_target); builder.setBuildPoint(&blocks.continue_target); @@ -1368,7 +1368,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn builder.setBuildPoint(&blocks.body); if (node->getBody()) - node->getBody()->traverse(this); // continue->cont, break->exit + node->getBody()->traverse(this); builder.createBranch(&blocks.continue_target); builder.setBuildPoint(&blocks.continue_target); diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 57e27e0..8e023ea 100755 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -852,7 +852,7 @@ void Builder::leaveFunction() if (unreachable) { // Given that this block is at the end of a function, it must be right after an // explicit return, just remove it. - function.popBlock(block); + function.removeBlock(block); } else { // We'll add a return instruction at the end of the current block, // which for a non-void function is really error recovery (?), as the source diff --git a/SPIRV/spvIR.h b/SPIRV/spvIR.h index 6736a13..70f27f7 100755 --- a/SPIRV/spvIR.h +++ b/SPIRV/spvIR.h @@ -52,6 +52,7 @@ #include "spirv.hpp" +#include #include #include #include @@ -235,7 +236,13 @@ public: Id getParamId(int p) { return parameterInstructions[p]->getResultId(); } void addBlock(Block* block) { blocks.push_back(block); } - void popBlock(Block*) { blocks.pop_back(); } + void removeBlock(Block* block) + { + auto found = find(blocks.begin(), blocks.end(), block); + assert(found != blocks.end()); + blocks.erase(found); + delete block; + } Module& getParent() const { return parent; } Block* getEntryBlock() const { return blocks.front(); } diff --git a/Test/baseResults/spv.for-notest.vert.out b/Test/baseResults/spv.for-notest.vert.out new file mode 100644 index 0000000..e55ef9b --- /dev/null +++ b/Test/baseResults/spv.for-notest.vert.out @@ -0,0 +1,50 @@ +spv.for-notest.vert +Warning, version 450 is not yet complete; most version-specific features are present, but some are missing. + + +Linked vertex stage: + + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 22 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Vertex 4 "main" 14 20 21 + Source GLSL 450 + Name 4 "main" + Name 8 "i" + Name 14 "r" + Name 20 "gl_VertexID" + Name 21 "gl_InstanceID" + Decorate 14(r) Location 0 + Decorate 20(gl_VertexID) BuiltIn VertexId + Decorate 21(gl_InstanceID) BuiltIn InstanceId + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeInt 32 1 + 7: TypePointer Function 6(int) + 9: 6(int) Constant 0 + 13: TypePointer Output 6(int) + 14(r): 13(ptr) Variable Output + 17: 6(int) Constant 1 + 19: TypePointer Input 6(int) + 20(gl_VertexID): 19(ptr) Variable Input +21(gl_InstanceID): 19(ptr) Variable Input + 4(main): 2 Function None 3 + 5: Label + 8(i): 7(ptr) Variable Function + Store 8(i) 9 + Branch 10 + 10: Label + 15: 6(int) Load 8(i) + Store 14(r) 15 + Branch 12 + 12: Label + 16: 6(int) Load 8(i) + 18: 6(int) IAdd 16 17 + Store 8(i) 18 + Branch 10 + FunctionEnd diff --git a/Test/spv.for-notest.vert b/Test/spv.for-notest.vert new file mode 100644 index 0000000..f40e666 --- /dev/null +++ b/Test/spv.for-notest.vert @@ -0,0 +1,6 @@ +#version 450 +layout(location=0) out highp int r; +void main() { + int i; + for (i=0; ; i++) { r = i; } +} -- 2.7.4