SPIR-V: Aggressively prune unreachable merge, continue target

More aggressively prune unreachable code as follows.
When no control flow edges reach a merge block or continue target:
- delete their contents so that:
  - a merge block becomes OpLabel, then OpUnreachable
  - a continue target becomes OpLabel, then an OpBranch back to the
    loop header
- any basic block which is dominated by such a merge block or continue
  target is removed as well.
- decorations targeting the removed instructions are removed.

Enables the SPIR-V builder post-processing step the GLSLANG_WEB case.
This commit is contained in:
David Neto 2019-10-21 14:50:31 -04:00
parent b131630e7c
commit 8c3d5b4b6c
44 changed files with 2398 additions and 1423 deletions

View File

@ -1630,11 +1630,11 @@ void TGlslangToSpvTraverser::finishSpv()
for (auto it = iOSet.cbegin(); it != iOSet.cend(); ++it)
entryPoint->addIdOperand(*it);
#ifndef GLSLANG_WEB
// Add capabilities, extensions, remove unneeded decorations, etc.,
// Add capabilities, extensions, remove unneeded decorations, etc.,
// based on the resulting SPIR-V.
// Note: WebGPU code generation must have the opportunity to aggressively
// prune unreachable merge blocks and continue targets.
builder.postProcess();
#endif
}
// Write the SPV into 'out'.

View File

@ -61,17 +61,22 @@ namespace {
// Use by calling visit() on the root block.
class ReadableOrderTraverser {
public:
explicit ReadableOrderTraverser(std::function<void(Block*)> callback) : callback_(callback) {}
ReadableOrderTraverser(std::function<void(Block*, spv::ReachReason, Block*)> callback)
: callback_(callback) {}
// Visits the block if it hasn't been visited already and isn't currently
// being delayed. Invokes callback(block), then descends into its
// being delayed. Invokes callback(block, why, header), then descends into its
// successors. Delays merge-block and continue-block processing until all
// the branches have been completed.
void visit(Block* block)
// the branches have been completed. If |block| is an unreachable merge block or
// an unreachable continue target, then |header| is the corresponding header block.
void visit(Block* block, spv::ReachReason why, Block* header)
{
assert(block);
if (why == spv::ReachViaControlFlow) {
reachableViaControlFlow_.insert(block);
}
if (visited_.count(block) || delayed_.count(block))
return;
callback_(block);
callback_(block, why, header);
visited_.insert(block);
Block* mergeBlock = nullptr;
Block* continueBlock = nullptr;
@ -87,27 +92,40 @@ public:
delayed_.insert(continueBlock);
}
}
const auto successors = block->getSuccessors();
for (auto it = successors.cbegin(); it != successors.cend(); ++it)
visit(*it);
if (why == spv::ReachViaControlFlow) {
const auto& successors = block->getSuccessors();
for (auto it = successors.cbegin(); it != successors.cend(); ++it)
visit(*it, why, nullptr);
}
if (continueBlock) {
const spv::ReachReason continueWhy =
(reachableViaControlFlow_.count(continueBlock) > 0)
? spv::ReachViaControlFlow
: spv::ReachDeadContinue;
delayed_.erase(continueBlock);
visit(continueBlock);
visit(continueBlock, continueWhy, block);
}
if (mergeBlock) {
const spv::ReachReason mergeWhy =
(reachableViaControlFlow_.count(mergeBlock) > 0)
? spv::ReachViaControlFlow
: spv::ReachDeadMerge;
delayed_.erase(mergeBlock);
visit(mergeBlock);
visit(mergeBlock, mergeWhy, block);
}
}
private:
std::function<void(Block*)> callback_;
std::function<void(Block*, spv::ReachReason, Block*)> callback_;
// Whether a block has already been visited or is being delayed.
std::unordered_set<Block *> visited_, delayed_;
// The set of blocks that actually are reached via control flow.
std::unordered_set<Block *> reachableViaControlFlow_;
};
}
void spv::inReadableOrder(Block* root, std::function<void(Block*)> callback)
void spv::inReadableOrder(Block* root, std::function<void(Block*, spv::ReachReason, Block*)> callback)
{
ReadableOrderTraverser(callback).visit(root);
ReadableOrderTraverser(callback).visit(root, spv::ReachViaControlFlow, nullptr);
}

View File

@ -683,14 +683,12 @@ public:
// based on the type of the base and the chain of dereferences.
Id accessChainGetInferredType();
// Add capabilities, extensions, remove unneeded decorations, etc.,
// Add capabilities, extensions, remove unneeded decorations, etc.,
// based on the resulting SPIR-V.
void postProcess();
// Hook to visit each instruction in a block in a function
void postProcess(Instruction&);
// Hook to visit each instruction in a reachable block in a function.
void postProcessReachable(const Instruction&);
// Hook to visit each non-32-bit sized float/int operation in a block.
void postProcessType(const Instruction&, spv::Id typeId);

View File

@ -39,6 +39,7 @@
#include <cassert>
#include <cstdlib>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
@ -319,16 +320,14 @@ void Builder::postProcess(Instruction& inst)
}
}
// Called for each instruction in a reachable block.
void Builder::postProcessReachable(const Instruction&)
{
// did have code here, but questionable to do so without deleting the instructions
}
// comment in header
void Builder::postProcess()
{
// reachableBlocks is the set of blockss reached via control flow, or which are
// unreachable continue targert or unreachable merge.
std::unordered_set<const Block*> reachableBlocks;
std::unordered_map<Block*, Block*> headerForUnreachableContinue;
std::unordered_set<Block*> unreachableMerges;
std::unordered_set<Id> unreachableDefinitions;
// Collect IDs defined in unreachable blocks. For each function, label the
// reachable blocks first. Then for each unreachable block, collect the
@ -336,16 +335,41 @@ void Builder::postProcess()
for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) {
Function* f = *fi;
Block* entry = f->getEntryBlock();
inReadableOrder(entry, [&reachableBlocks](const Block* b) { reachableBlocks.insert(b); });
inReadableOrder(entry,
[&reachableBlocks, &unreachableMerges, &headerForUnreachableContinue]
(Block* b, ReachReason why, Block* header) {
reachableBlocks.insert(b);
if (why == ReachDeadContinue) headerForUnreachableContinue[b] = header;
if (why == ReachDeadMerge) unreachableMerges.insert(b);
});
for (auto bi = f->getBlocks().cbegin(); bi != f->getBlocks().cend(); bi++) {
Block* b = *bi;
if (reachableBlocks.count(b) == 0) {
for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ii++)
if (unreachableMerges.count(b) != 0 || headerForUnreachableContinue.count(b) != 0) {
auto ii = b->getInstructions().cbegin();
++ii; // Keep potential decorations on the label.
for (; ii != b->getInstructions().cend(); ++ii)
unreachableDefinitions.insert(ii->get()->getResultId());
} else if (reachableBlocks.count(b) == 0) {
// The normal case for unreachable code. All definitions are considered dead.
for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ++ii)
unreachableDefinitions.insert(ii->get()->getResultId());
}
}
}
// Modify unreachable merge blocks and unreachable continue targets.
// Delete their contents.
for (auto mergeIter = unreachableMerges.begin(); mergeIter != unreachableMerges.end(); ++mergeIter) {
(*mergeIter)->rewriteAsCanonicalUnreachableMerge();
}
for (auto continueIter = headerForUnreachableContinue.begin();
continueIter != headerForUnreachableContinue.end();
++continueIter) {
Block* continue_target = continueIter->first;
Block* header = continueIter->second;
continue_target->rewriteAsCanonicalUnreachableContinue(header);
}
// Remove unneeded decorations, for unreachable instructions
decorations.erase(std::remove_if(decorations.begin(), decorations.end(),
[&unreachableDefinitions](std::unique_ptr<Instruction>& I) -> bool {
@ -374,13 +398,6 @@ void Builder::postProcess()
}
}
// process all reachable instructions...
for (auto bi = reachableBlocks.cbegin(); bi != reachableBlocks.cend(); ++bi) {
const Block* block = *bi;
const auto function = [this](const std::unique_ptr<Instruction>& inst) { postProcessReachable(*inst.get()); };
std::for_each(block->getInstructions().begin(), block->getInstructions().end(), function);
}
// process all block-contained instructions
for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) {
Function* f = *fi;

View File

@ -226,6 +226,36 @@ public:
return nullptr;
}
// Change this block into a canonical dead merge block. Delete instructions
// as necessary. A canonical dead merge block has only an OpLabel and an
// OpUnreachable.
void rewriteAsCanonicalUnreachableMerge() {
assert(localVariables.empty());
// Delete all instructions except for the label.
assert(instructions.size() > 0);
instructions.resize(1);
successors.clear();
Instruction* unreachable = new Instruction(OpUnreachable);
addInstruction(std::unique_ptr<Instruction>(unreachable));
}
// Change this block into a canonical dead continue target branching to the
// given header ID. Delete instructions as necessary. A canonical dead continue
// target has only an OpLabel and an unconditional branch back to the corresponding
// header.
void rewriteAsCanonicalUnreachableContinue(Block* header) {
assert(localVariables.empty());
// Delete all instructions except for the label.
assert(instructions.size() > 0);
instructions.resize(1);
successors.clear();
// Add OpBranch back to the header.
assert(header != nullptr);
Instruction* branch = new Instruction(OpBranch);
branch->addIdOperand(header->getId());
addInstruction(std::move(std::unique_ptr<Instruction>(branch)));
successors.push_back(header);
}
bool isTerminated() const
{
switch (instructions.back()->getOpCode()) {
@ -235,6 +265,7 @@ public:
case OpKill:
case OpReturn:
case OpReturnValue:
case OpUnreachable:
return true;
default:
return false;
@ -268,10 +299,24 @@ protected:
bool unreachable;
};
// The different reasons for reaching a block in the inReadableOrder traversal.
typedef enum ReachReason {
// Reachable from the entry block via transfers of control, i.e. branches.
ReachViaControlFlow = 0,
// A continue target that is not reachable via control flow.
ReachDeadContinue,
// A merge block that is not reachable via control flow.
ReachDeadMerge
};
// Traverses the control-flow graph rooted at root in an order suited for
// readable code generation. Invokes callback at every node in the traversal
// order.
void inReadableOrder(Block* root, std::function<void(Block*)> callback);
// order. The callback arguments are:
// - the block,
// - the reason we reached the block,
// - if the reason was that block is an unreachable continue or unreachable merge block
// then the last parameter is the corresponding header block.
void inReadableOrder(Block* root, std::function<void(Block*, ReachReason, Block* header)> callback);
//
// SPIR-V IR Function.
@ -321,7 +366,7 @@ public:
parameterInstructions[p]->dump(out);
// Blocks
inReadableOrder(blocks[0], [&out](const Block* b) { b->dump(out); });
inReadableOrder(blocks[0], [&out](const Block* b, ReachReason, Block*) { b->dump(out); });
Instruction end(0, 0, OpFunctionEnd);
end.dump(out);
}

View File

@ -988,7 +988,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
// Set base bindings
shader->setShiftBinding(res, baseBinding[res][compUnit.stage]);
// Set bindings for particular resource sets
// TODO: use a range based for loop here, when available in all environments.
for (auto i = baseBindingForSet[res][compUnit.stage].begin();

View File

@ -240,6 +240,5 @@ Validation failed
60: 7(fvec4) CompositeConstruct 59 59 59 59
ReturnValue 60
30: Label
62: 7(fvec4) Undef
ReturnValue 62
Unreachable
FunctionEnd

View File

@ -2,68 +2,95 @@ hlsl.doLoop.frag
Shader version: 500
gl_FragCoord origin is upper left
0:? Sequence
0:2 Function Definition: @PixelShaderFunction(f1; ( temp 4-component vector of float)
0:2 Function Parameters:
0:2 'input' ( in float)
0:1 Function Definition: f0( ( temp void)
0:1 Function Parameters:
0:? Sequence
0:3 Loop with condition not tested first: Unroll
0:3 Loop Condition
0:3 Constant:
0:3 false (const bool)
0:3 No loop body
0:4 Loop with condition not tested first: Unroll
0:4 Loop Condition
0:4 Constant:
0:4 false (const bool)
0:4 No loop body
0:5 Loop with condition not tested first
0:5 Loop Condition
0:5 Compare Greater Than ( temp bool)
0:5 'input' ( in float)
0:5 Constant:
0:5 2.000000
0:5 Loop Body
0:? Sequence
0:5 Branch: Return with expression
0:5 Construct vec4 ( temp 4-component vector of float)
0:5 'input' ( in float)
0:6 Loop with condition not tested first
0:2 Loop with condition not tested first: Unroll
0:2 Loop Condition
0:2 Constant:
0:2 false (const bool)
0:2 No loop body
0:5 Function Definition: f1( ( temp void)
0:5 Function Parameters:
0:? Sequence
0:6 Loop with condition not tested first: Unroll
0:6 Loop Condition
0:6 Compare Less Than ( temp bool)
0:6 'input' ( in float)
0:6 Constant:
0:6 10.000000
0:6 Loop Body
0:6 Pre-Increment ( temp float)
0:6 'input' ( in float)
0:7 Loop with condition not tested first
0:7 Loop Condition
0:7 Compare Less Than ( temp bool)
0:7 Pre-Increment ( temp float)
0:7 'input' ( in float)
0:7 Constant:
0:7 10.000000
0:7 Loop Body
0:7 Loop with condition tested first
0:7 Loop Condition
0:7 Compare Less Than ( temp bool)
0:7 Pre-Increment ( temp float)
0:7 'input' ( in float)
0:7 Constant:
0:7 10.000000
0:7 No loop body
0:8 Branch: Return with expression
0:8 Construct vec4 ( temp 4-component vector of float)
0:8 'input' ( in float)
0:2 Function Definition: PixelShaderFunction( ( temp void)
0:2 Function Parameters:
0:6 Constant:
0:6 false (const bool)
0:6 No loop body
0:9 Function Definition: f2(f1; ( temp float)
0:9 Function Parameters:
0:9 'input' ( in float)
0:? Sequence
0:2 move second child to first child ( temp float)
0:10 Loop with condition not tested first
0:10 Loop Condition
0:10 Compare Greater Than ( temp bool)
0:10 'input' ( in float)
0:10 Constant:
0:10 2.000000
0:10 Loop Body
0:? Sequence
0:10 Branch: Return with expression
0:10 Construct float ( temp float)
0:10 Construct vec4 ( temp 4-component vector of float)
0:10 'input' ( in float)
0:13 Function Definition: f3(f1; ( temp void)
0:13 Function Parameters:
0:13 'input' ( in float)
0:? Sequence
0:14 Loop with condition not tested first
0:14 Loop Condition
0:14 Compare Less Than ( temp bool)
0:14 'input' ( in float)
0:14 Constant:
0:14 10.000000
0:14 Loop Body
0:14 Pre-Increment ( temp float)
0:14 'input' ( in float)
0:17 Function Definition: f4(f1; ( temp void)
0:17 Function Parameters:
0:17 'input' ( in float)
0:? Sequence
0:18 Loop with condition not tested first
0:18 Loop Condition
0:18 Compare Less Than ( temp bool)
0:18 Pre-Increment ( temp float)
0:18 'input' ( in float)
0:18 Constant:
0:18 10.000000
0:18 Loop Body
0:18 Loop with condition tested first
0:18 Loop Condition
0:18 Compare Less Than ( temp bool)
0:18 Pre-Increment ( temp float)
0:18 'input' ( in float)
0:18 Constant:
0:18 10.000000
0:18 No loop body
0:22 Function Definition: @PixelShaderFunction(f1; ( temp 4-component vector of float)
0:22 Function Parameters:
0:22 'input' ( in float)
0:? Sequence
0:23 Function Call: f0( ( temp void)
0:24 Function Call: f1( ( temp void)
0:25 Function Call: f2(f1; ( temp float)
0:25 'input' ( in float)
0:26 Function Call: f3(f1; ( temp void)
0:26 'input' ( in float)
0:27 Function Call: f4(f1; ( temp void)
0:27 'input' ( in float)
0:28 Branch: Return with expression
0:28 Construct vec4 ( temp 4-component vector of float)
0:28 'input' ( in float)
0:22 Function Definition: PixelShaderFunction( ( temp void)
0:22 Function Parameters:
0:? Sequence
0:22 move second child to first child ( temp float)
0:? 'input' ( temp float)
0:? 'input' (layout( location=0) in float)
0:2 move second child to first child ( temp 4-component vector of float)
0:22 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:2 Function Call: @PixelShaderFunction(f1; ( temp 4-component vector of float)
0:22 Function Call: @PixelShaderFunction(f1; ( temp 4-component vector of float)
0:? 'input' ( temp float)
0:? Linker Objects
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
@ -76,68 +103,95 @@ Linked fragment stage:
Shader version: 500
gl_FragCoord origin is upper left
0:? Sequence
0:2 Function Definition: @PixelShaderFunction(f1; ( temp 4-component vector of float)
0:2 Function Parameters:
0:2 'input' ( in float)
0:1 Function Definition: f0( ( temp void)
0:1 Function Parameters:
0:? Sequence
0:3 Loop with condition not tested first: Unroll
0:3 Loop Condition
0:3 Constant:
0:3 false (const bool)
0:3 No loop body
0:4 Loop with condition not tested first: Unroll
0:4 Loop Condition
0:4 Constant:
0:4 false (const bool)
0:4 No loop body
0:5 Loop with condition not tested first
0:5 Loop Condition
0:5 Compare Greater Than ( temp bool)
0:5 'input' ( in float)
0:5 Constant:
0:5 2.000000
0:5 Loop Body
0:? Sequence
0:5 Branch: Return with expression
0:5 Construct vec4 ( temp 4-component vector of float)
0:5 'input' ( in float)
0:6 Loop with condition not tested first
0:2 Loop with condition not tested first: Unroll
0:2 Loop Condition
0:2 Constant:
0:2 false (const bool)
0:2 No loop body
0:5 Function Definition: f1( ( temp void)
0:5 Function Parameters:
0:? Sequence
0:6 Loop with condition not tested first: Unroll
0:6 Loop Condition
0:6 Compare Less Than ( temp bool)
0:6 'input' ( in float)
0:6 Constant:
0:6 10.000000
0:6 Loop Body
0:6 Pre-Increment ( temp float)
0:6 'input' ( in float)
0:7 Loop with condition not tested first
0:7 Loop Condition
0:7 Compare Less Than ( temp bool)
0:7 Pre-Increment ( temp float)
0:7 'input' ( in float)
0:7 Constant:
0:7 10.000000
0:7 Loop Body
0:7 Loop with condition tested first
0:7 Loop Condition
0:7 Compare Less Than ( temp bool)
0:7 Pre-Increment ( temp float)
0:7 'input' ( in float)
0:7 Constant:
0:7 10.000000
0:7 No loop body
0:8 Branch: Return with expression
0:8 Construct vec4 ( temp 4-component vector of float)
0:8 'input' ( in float)
0:2 Function Definition: PixelShaderFunction( ( temp void)
0:2 Function Parameters:
0:6 Constant:
0:6 false (const bool)
0:6 No loop body
0:9 Function Definition: f2(f1; ( temp float)
0:9 Function Parameters:
0:9 'input' ( in float)
0:? Sequence
0:2 move second child to first child ( temp float)
0:10 Loop with condition not tested first
0:10 Loop Condition
0:10 Compare Greater Than ( temp bool)
0:10 'input' ( in float)
0:10 Constant:
0:10 2.000000
0:10 Loop Body
0:? Sequence
0:10 Branch: Return with expression
0:10 Construct float ( temp float)
0:10 Construct vec4 ( temp 4-component vector of float)
0:10 'input' ( in float)
0:13 Function Definition: f3(f1; ( temp void)
0:13 Function Parameters:
0:13 'input' ( in float)
0:? Sequence
0:14 Loop with condition not tested first
0:14 Loop Condition
0:14 Compare Less Than ( temp bool)
0:14 'input' ( in float)
0:14 Constant:
0:14 10.000000
0:14 Loop Body
0:14 Pre-Increment ( temp float)
0:14 'input' ( in float)
0:17 Function Definition: f4(f1; ( temp void)
0:17 Function Parameters:
0:17 'input' ( in float)
0:? Sequence
0:18 Loop with condition not tested first
0:18 Loop Condition
0:18 Compare Less Than ( temp bool)
0:18 Pre-Increment ( temp float)
0:18 'input' ( in float)
0:18 Constant:
0:18 10.000000
0:18 Loop Body
0:18 Loop with condition tested first
0:18 Loop Condition
0:18 Compare Less Than ( temp bool)
0:18 Pre-Increment ( temp float)
0:18 'input' ( in float)
0:18 Constant:
0:18 10.000000
0:18 No loop body
0:22 Function Definition: @PixelShaderFunction(f1; ( temp 4-component vector of float)
0:22 Function Parameters:
0:22 'input' ( in float)
0:? Sequence
0:23 Function Call: f0( ( temp void)
0:24 Function Call: f1( ( temp void)
0:25 Function Call: f2(f1; ( temp float)
0:25 'input' ( in float)
0:26 Function Call: f3(f1; ( temp void)
0:26 'input' ( in float)
0:27 Function Call: f4(f1; ( temp void)
0:27 'input' ( in float)
0:28 Branch: Return with expression
0:28 Construct vec4 ( temp 4-component vector of float)
0:28 'input' ( in float)
0:22 Function Definition: PixelShaderFunction( ( temp void)
0:22 Function Parameters:
0:? Sequence
0:22 move second child to first child ( temp float)
0:? 'input' ( temp float)
0:? 'input' (layout( location=0) in float)
0:2 move second child to first child ( temp 4-component vector of float)
0:22 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:2 Function Call: @PixelShaderFunction(f1; ( temp 4-component vector of float)
0:22 Function Call: @PixelShaderFunction(f1; ( temp 4-component vector of float)
0:? 'input' ( temp float)
0:? Linker Objects
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
@ -145,127 +199,176 @@ gl_FragCoord origin is upper left
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 71
// Id's are bound by 99
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "PixelShaderFunction" 64 67
EntryPoint Fragment 4 "PixelShaderFunction" 92 95
ExecutionMode 4 OriginUpperLeft
Source HLSL 500
Name 4 "PixelShaderFunction"
Name 11 "@PixelShaderFunction(f1;"
Name 10 "input"
Name 62 "input"
Name 64 "input"
Name 67 "@entryPointOutput"
Name 68 "param"
Decorate 64(input) Location 0
Decorate 67(@entryPointOutput) Location 0
Name 6 "f0("
Name 8 "f1("
Name 14 "f2(f1;"
Name 13 "input"
Name 18 "f3(f1;"
Name 17 "input"
Name 21 "f4(f1;"
Name 20 "input"
Name 26 "@PixelShaderFunction(f1;"
Name 25 "input"
Name 77 "param"
Name 80 "param"
Name 83 "param"
Name 90 "input"
Name 92 "input"
Name 95 "@entryPointOutput"
Name 96 "param"
Decorate 92(input) Location 0
Decorate 95(@entryPointOutput) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypePointer Function 6(float)
8: TypeVector 6(float) 4
9: TypeFunction 8(fvec4) 7(ptr)
17: TypeBool
18: 17(bool) ConstantFalse
31: 6(float) Constant 1073741824
38: 6(float) Constant 1065353216
41: 6(float) Constant 1092616192
63: TypePointer Input 6(float)
64(input): 63(ptr) Variable Input
66: TypePointer Output 8(fvec4)
67(@entryPointOutput): 66(ptr) Variable Output
10: TypeFloat 32
11: TypePointer Function 10(float)
12: TypeFunction 10(float) 11(ptr)
16: TypeFunction 2 11(ptr)
23: TypeVector 10(float) 4
24: TypeFunction 23(fvec4) 11(ptr)
32: TypeBool
33: 32(bool) ConstantFalse
47: 10(float) Constant 1073741824
55: 10(float) Constant 1065353216
58: 10(float) Constant 1092616192
91: TypePointer Input 10(float)
92(input): 91(ptr) Variable Input
94: TypePointer Output 23(fvec4)
95(@entryPointOutput): 94(ptr) Variable Output
4(PixelShaderFunction): 2 Function None 3
5: Label
62(input): 7(ptr) Variable Function
68(param): 7(ptr) Variable Function
65: 6(float) Load 64(input)
Store 62(input) 65
69: 6(float) Load 62(input)
Store 68(param) 69
70: 8(fvec4) FunctionCall 11(@PixelShaderFunction(f1;) 68(param)
Store 67(@entryPointOutput) 70
90(input): 11(ptr) Variable Function
96(param): 11(ptr) Variable Function
93: 10(float) Load 92(input)
Store 90(input) 93
97: 10(float) Load 90(input)
Store 96(param) 97
98: 23(fvec4) FunctionCall 26(@PixelShaderFunction(f1;) 96(param)
Store 95(@entryPointOutput) 98
Return
FunctionEnd
11(@PixelShaderFunction(f1;): 8(fvec4) Function None 9
10(input): 7(ptr) FunctionParameter
12: Label
Branch 13
13: Label
LoopMerge 15 16 Unroll
Branch 14
14: Label
Branch 16
16: Label
BranchConditional 18 13 15
15: Label
Branch 19
19: Label
LoopMerge 21 22 Unroll
Branch 20
20: Label
Branch 22
22: Label
BranchConditional 18 19 21
21: Label
Branch 23
23: Label
LoopMerge 25 26 None
Branch 24
24: Label
27: 6(float) Load 10(input)
28: 8(fvec4) CompositeConstruct 27 27 27 27
ReturnValue 28
26: Label
30: 6(float) Load 10(input)
32: 17(bool) FOrdGreaterThan 30 31
BranchConditional 32 23 25
25: Label
Branch 33
33: Label
LoopMerge 35 36 None
6(f0(): 2 Function None 3
7: Label
Branch 28
28: Label
LoopMerge 30 31 Unroll
Branch 29
29: Label
Branch 31
31: Label
BranchConditional 33 28 30
30: Label
Return
FunctionEnd
8(f1(): 2 Function None 3
9: Label
Branch 34
34: Label
37: 6(float) Load 10(input)
39: 6(float) FAdd 37 38
Store 10(input) 39
Branch 36
36: Label
40: 6(float) Load 10(input)
42: 17(bool) FOrdLessThan 40 41
BranchConditional 42 33 35
LoopMerge 36 37 Unroll
Branch 35
35: Label
Branch 43
43: Label
LoopMerge 45 46 None
Branch 44
44: Label
Branch 47
47: Label
LoopMerge 49 50 None
Branch 37
37: Label
BranchConditional 33 34 36
36: Label
Return
FunctionEnd
14(f2(f1;): 10(float) Function None 12
13(input): 11(ptr) FunctionParameter
15: Label
Branch 38
38: Label
LoopMerge 40 41 None
Branch 39
39: Label
42: 10(float) Load 13(input)
43: 23(fvec4) CompositeConstruct 42 42 42 42
44: 10(float) CompositeExtract 43 0
ReturnValue 44
41: Label
Branch 38
40: Label
Unreachable
FunctionEnd
18(f3(f1;): 2 Function None 16
17(input): 11(ptr) FunctionParameter
19: Label
Branch 50
50: Label
LoopMerge 52 53 None
Branch 51
51: Label
52: 6(float) Load 10(input)
53: 6(float) FAdd 52 38
Store 10(input) 53
54: 17(bool) FOrdLessThan 53 41
BranchConditional 54 48 49
48: Label
Branch 50
50: Label
Branch 47
49: Label
Branch 46
46: Label
55: 6(float) Load 10(input)
56: 6(float) FAdd 55 38
Store 10(input) 56
57: 17(bool) FOrdLessThan 56 41
BranchConditional 57 43 45
45: Label
58: 6(float) Load 10(input)
59: 8(fvec4) CompositeConstruct 58 58 58 58
ReturnValue 59
54: 10(float) Load 17(input)
56: 10(float) FAdd 54 55
Store 17(input) 56
Branch 53
53: Label
57: 10(float) Load 17(input)
59: 32(bool) FOrdLessThan 57 58
BranchConditional 59 50 52
52: Label
Return
FunctionEnd
21(f4(f1;): 2 Function None 16
20(input): 11(ptr) FunctionParameter
22: Label
Branch 60
60: Label
LoopMerge 62 63 None
Branch 61
61: Label
Branch 64
64: Label
LoopMerge 66 67 None
Branch 68
68: Label
69: 10(float) Load 20(input)
70: 10(float) FAdd 69 55
Store 20(input) 70
71: 32(bool) FOrdLessThan 70 58
BranchConditional 71 65 66
65: Label
Branch 67
67: Label
Branch 64
66: Label
Branch 63
63: Label
72: 10(float) Load 20(input)
73: 10(float) FAdd 72 55
Store 20(input) 73
74: 32(bool) FOrdLessThan 73 58
BranchConditional 74 60 62
62: Label
Return
FunctionEnd
26(@PixelShaderFunction(f1;): 23(fvec4) Function None 24
25(input): 11(ptr) FunctionParameter
27: Label
77(param): 11(ptr) Variable Function
80(param): 11(ptr) Variable Function
83(param): 11(ptr) Variable Function
75: 2 FunctionCall 6(f0()
76: 2 FunctionCall 8(f1()
78: 10(float) Load 25(input)
Store 77(param) 78
79: 10(float) FunctionCall 14(f2(f1;) 77(param)
81: 10(float) Load 25(input)
Store 80(param) 81
82: 2 FunctionCall 18(f3(f1;) 80(param)
84: 10(float) Load 25(input)
Store 83(param) 84
85: 2 FunctionCall 21(f4(f1;) 83(param)
86: 10(float) Load 25(input)
87: 23(fvec4) CompositeConstruct 86 86 86 86
ReturnValue 87
FunctionEnd

File diff suppressed because it is too large Load Diff

View File

@ -2,104 +2,116 @@ hlsl.if.frag
Shader version: 500
gl_FragCoord origin is upper left
0:? Sequence
0:2 Function Definition: @PixelShaderFunction(vf4; ( temp 4-component vector of float)
0:2 Function Parameters:
0:2 'input' ( in 4-component vector of float)
0:1 Function Definition: f0(vf4; ( temp 4-component vector of float)
0:1 Function Parameters:
0:1 'input' ( in 4-component vector of float)
0:? Sequence
0:3 Test condition and select ( temp void)
0:3 Condition
0:3 all ( temp bool)
0:3 Equal ( temp 4-component vector of bool)
0:3 'input' ( in 4-component vector of float)
0:3 'input' ( in 4-component vector of float)
0:3 true case
0:4 Branch: Return with expression
0:4 'input' ( in 4-component vector of float)
0:6 Test condition and select ( temp void)
0:6 Condition
0:6 all ( temp bool)
0:6 Equal ( temp 4-component vector of bool)
0:6 'input' ( in 4-component vector of float)
0:6 'input' ( in 4-component vector of float)
0:6 true case
0:7 Branch: Return with expression
0:7 'input' ( in 4-component vector of float)
0:6 false case
0:9 Branch: Return with expression
0:9 Negate value ( temp 4-component vector of float)
0:2 Test condition and select ( temp void)
0:2 Condition
0:2 all ( temp bool)
0:2 Equal ( temp 4-component vector of bool)
0:2 'input' ( in 4-component vector of float)
0:2 'input' ( in 4-component vector of float)
0:2 true case
0:3 Branch: Return with expression
0:3 'input' ( in 4-component vector of float)
0:2 false case
0:5 Branch: Return with expression
0:5 Negate value ( temp 4-component vector of float)
0:5 'input' ( in 4-component vector of float)
0:8 Function Definition: f1(vf4; ( temp 4-component vector of float)
0:8 Function Parameters:
0:8 'input' ( in 4-component vector of float)
0:? Sequence
0:9 Test condition and select ( temp void)
0:9 Condition
0:9 all ( temp bool)
0:9 Equal ( temp 4-component vector of bool)
0:9 'input' ( in 4-component vector of float)
0:11 Test condition and select ( temp void)
0:11 Condition
0:11 all ( temp bool)
0:11 Equal ( temp 4-component vector of bool)
0:11 'input' ( in 4-component vector of float)
0:11 'input' ( in 4-component vector of float)
0:11 true case is null
0:14 Test condition and select ( temp void)
0:14 Condition
0:14 all ( temp bool)
0:14 Equal ( temp 4-component vector of bool)
0:14 'input' ( in 4-component vector of float)
0:14 'input' ( in 4-component vector of float)
0:14 true case is null
0:19 Test condition and select ( temp void): Flatten
0:19 Condition
0:19 all ( temp bool)
0:19 Equal ( temp 4-component vector of bool)
0:19 'input' ( in 4-component vector of float)
0:19 'input' ( in 4-component vector of float)
0:19 true case
0:9 'input' ( in 4-component vector of float)
0:9 true case
0:? Sequence
0:20 Branch: Return with expression
0:20 'input' ( in 4-component vector of float)
0:10 Branch: Return with expression
0:10 'input' ( in 4-component vector of float)
0:9 false case
0:? Sequence
0:12 Branch: Return with expression
0:12 Negate value ( temp 4-component vector of float)
0:12 'input' ( in 4-component vector of float)
0:17 Function Definition: @PixelShaderFunction(vf4; ( temp 4-component vector of float)
0:17 Function Parameters:
0:17 'input' ( in 4-component vector of float)
0:? Sequence
0:18 Test condition and select ( temp void)
0:18 Condition
0:18 all ( temp bool)
0:18 Equal ( temp 4-component vector of bool)
0:18 'input' ( in 4-component vector of float)
0:18 'input' ( in 4-component vector of float)
0:18 true case
0:19 Branch: Return with expression
0:19 'input' ( in 4-component vector of float)
0:21 Function Call: f0(vf4; ( temp 4-component vector of float)
0:21 'input' ( in 4-component vector of float)
0:23 Test condition and select ( temp void)
0:23 Condition
0:23 all ( temp bool)
0:23 Equal ( temp 4-component vector of bool)
0:23 'input' ( in 4-component vector of float)
0:23 'input' ( in 4-component vector of float)
0:23 true case
0:23 true case is null
0:26 Test condition and select ( temp void)
0:26 Condition
0:26 all ( temp bool)
0:26 Equal ( temp 4-component vector of bool)
0:26 'input' ( in 4-component vector of float)
0:26 'input' ( in 4-component vector of float)
0:26 true case is null
0:31 Test condition and select ( temp void): Flatten
0:31 Condition
0:31 all ( temp bool)
0:31 Equal ( temp 4-component vector of bool)
0:31 'input' ( in 4-component vector of float)
0:31 'input' ( in 4-component vector of float)
0:31 true case
0:? Sequence
0:24 Branch: Return with expression
0:24 'input' ( in 4-component vector of float)
0:23 false case
0:? Sequence
0:26 Branch: Return with expression
0:26 Negate value ( temp 4-component vector of float)
0:26 'input' ( in 4-component vector of float)
0:30 Test condition and select ( temp void)
0:30 Condition
0:30 Convert float to bool ( temp bool)
0:30 move second child to first child ( temp float)
0:30 'ii' ( temp float)
0:30 direct index ( temp float)
0:30 'input' ( in 4-component vector of float)
0:30 Constant:
0:30 2 (const int)
0:30 true case
0:31 Pre-Increment ( temp float)
0:31 'ii' ( temp float)
0:32 Pre-Increment ( temp int)
0:32 'ii' ( temp int)
0:33 Test condition and select ( temp void)
0:33 Condition
0:33 Compare Equal ( temp bool)
0:33 Convert int to float ( temp float)
0:33 'ii' ( temp int)
0:33 Constant:
0:33 1.000000
0:33 true case
0:34 Pre-Increment ( temp int)
0:34 'ii' ( temp int)
0:2 Function Definition: PixelShaderFunction( ( temp void)
0:2 Function Parameters:
0:32 Branch: Return with expression
0:32 'input' ( in 4-component vector of float)
0:35 Function Call: f1(vf4; ( temp 4-component vector of float)
0:35 'input' ( in 4-component vector of float)
0:38 Test condition and select ( temp void)
0:38 Condition
0:38 Convert float to bool ( temp bool)
0:38 move second child to first child ( temp float)
0:38 'ii' ( temp float)
0:38 direct index ( temp float)
0:38 'input' ( in 4-component vector of float)
0:38 Constant:
0:38 2 (const int)
0:38 true case
0:39 Pre-Increment ( temp float)
0:39 'ii' ( temp float)
0:40 Pre-Increment ( temp int)
0:40 'ii' ( temp int)
0:41 Test condition and select ( temp void)
0:41 Condition
0:41 Compare Equal ( temp bool)
0:41 Convert int to float ( temp float)
0:41 'ii' ( temp int)
0:41 Constant:
0:41 1.000000
0:41 true case
0:42 Pre-Increment ( temp int)
0:42 'ii' ( temp int)
0:17 Function Definition: PixelShaderFunction( ( temp void)
0:17 Function Parameters:
0:? Sequence
0:2 move second child to first child ( temp 4-component vector of float)
0:17 move second child to first child ( temp 4-component vector of float)
0:? 'input' ( temp 4-component vector of float)
0:? 'input' (layout( location=0) in 4-component vector of float)
0:2 move second child to first child ( temp 4-component vector of float)
0:17 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:2 Function Call: @PixelShaderFunction(vf4; ( temp 4-component vector of float)
0:17 Function Call: @PixelShaderFunction(vf4; ( temp 4-component vector of float)
0:? 'input' ( temp 4-component vector of float)
0:? Linker Objects
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
@ -112,104 +124,116 @@ Linked fragment stage:
Shader version: 500
gl_FragCoord origin is upper left
0:? Sequence
0:2 Function Definition: @PixelShaderFunction(vf4; ( temp 4-component vector of float)
0:2 Function Parameters:
0:2 'input' ( in 4-component vector of float)
0:1 Function Definition: f0(vf4; ( temp 4-component vector of float)
0:1 Function Parameters:
0:1 'input' ( in 4-component vector of float)
0:? Sequence
0:3 Test condition and select ( temp void)
0:3 Condition
0:3 all ( temp bool)
0:3 Equal ( temp 4-component vector of bool)
0:3 'input' ( in 4-component vector of float)
0:3 'input' ( in 4-component vector of float)
0:3 true case
0:4 Branch: Return with expression
0:4 'input' ( in 4-component vector of float)
0:6 Test condition and select ( temp void)
0:6 Condition
0:6 all ( temp bool)
0:6 Equal ( temp 4-component vector of bool)
0:6 'input' ( in 4-component vector of float)
0:6 'input' ( in 4-component vector of float)
0:6 true case
0:7 Branch: Return with expression
0:7 'input' ( in 4-component vector of float)
0:6 false case
0:9 Branch: Return with expression
0:9 Negate value ( temp 4-component vector of float)
0:2 Test condition and select ( temp void)
0:2 Condition
0:2 all ( temp bool)
0:2 Equal ( temp 4-component vector of bool)
0:2 'input' ( in 4-component vector of float)
0:2 'input' ( in 4-component vector of float)
0:2 true case
0:3 Branch: Return with expression
0:3 'input' ( in 4-component vector of float)
0:2 false case
0:5 Branch: Return with expression
0:5 Negate value ( temp 4-component vector of float)
0:5 'input' ( in 4-component vector of float)
0:8 Function Definition: f1(vf4; ( temp 4-component vector of float)
0:8 Function Parameters:
0:8 'input' ( in 4-component vector of float)
0:? Sequence
0:9 Test condition and select ( temp void)
0:9 Condition
0:9 all ( temp bool)
0:9 Equal ( temp 4-component vector of bool)
0:9 'input' ( in 4-component vector of float)
0:11 Test condition and select ( temp void)
0:11 Condition
0:11 all ( temp bool)
0:11 Equal ( temp 4-component vector of bool)
0:11 'input' ( in 4-component vector of float)
0:11 'input' ( in 4-component vector of float)
0:11 true case is null
0:14 Test condition and select ( temp void)
0:14 Condition
0:14 all ( temp bool)
0:14 Equal ( temp 4-component vector of bool)
0:14 'input' ( in 4-component vector of float)
0:14 'input' ( in 4-component vector of float)
0:14 true case is null
0:19 Test condition and select ( temp void): Flatten
0:19 Condition
0:19 all ( temp bool)
0:19 Equal ( temp 4-component vector of bool)
0:19 'input' ( in 4-component vector of float)
0:19 'input' ( in 4-component vector of float)
0:19 true case
0:9 'input' ( in 4-component vector of float)
0:9 true case
0:? Sequence
0:20 Branch: Return with expression
0:20 'input' ( in 4-component vector of float)
0:10 Branch: Return with expression
0:10 'input' ( in 4-component vector of float)
0:9 false case
0:? Sequence
0:12 Branch: Return with expression
0:12 Negate value ( temp 4-component vector of float)
0:12 'input' ( in 4-component vector of float)
0:17 Function Definition: @PixelShaderFunction(vf4; ( temp 4-component vector of float)
0:17 Function Parameters:
0:17 'input' ( in 4-component vector of float)
0:? Sequence
0:18 Test condition and select ( temp void)
0:18 Condition
0:18 all ( temp bool)
0:18 Equal ( temp 4-component vector of bool)
0:18 'input' ( in 4-component vector of float)
0:18 'input' ( in 4-component vector of float)
0:18 true case
0:19 Branch: Return with expression
0:19 'input' ( in 4-component vector of float)
0:21 Function Call: f0(vf4; ( temp 4-component vector of float)
0:21 'input' ( in 4-component vector of float)
0:23 Test condition and select ( temp void)
0:23 Condition
0:23 all ( temp bool)
0:23 Equal ( temp 4-component vector of bool)
0:23 'input' ( in 4-component vector of float)
0:23 'input' ( in 4-component vector of float)
0:23 true case
0:23 true case is null
0:26 Test condition and select ( temp void)
0:26 Condition
0:26 all ( temp bool)
0:26 Equal ( temp 4-component vector of bool)
0:26 'input' ( in 4-component vector of float)
0:26 'input' ( in 4-component vector of float)
0:26 true case is null
0:31 Test condition and select ( temp void): Flatten
0:31 Condition
0:31 all ( temp bool)
0:31 Equal ( temp 4-component vector of bool)
0:31 'input' ( in 4-component vector of float)
0:31 'input' ( in 4-component vector of float)
0:31 true case
0:? Sequence
0:24 Branch: Return with expression
0:24 'input' ( in 4-component vector of float)
0:23 false case
0:? Sequence
0:26 Branch: Return with expression
0:26 Negate value ( temp 4-component vector of float)
0:26 'input' ( in 4-component vector of float)
0:30 Test condition and select ( temp void)
0:30 Condition
0:30 Convert float to bool ( temp bool)
0:30 move second child to first child ( temp float)
0:30 'ii' ( temp float)
0:30 direct index ( temp float)
0:30 'input' ( in 4-component vector of float)
0:30 Constant:
0:30 2 (const int)
0:30 true case
0:31 Pre-Increment ( temp float)
0:31 'ii' ( temp float)
0:32 Pre-Increment ( temp int)
0:32 'ii' ( temp int)
0:33 Test condition and select ( temp void)
0:33 Condition
0:33 Compare Equal ( temp bool)
0:33 Convert int to float ( temp float)
0:33 'ii' ( temp int)
0:33 Constant:
0:33 1.000000
0:33 true case
0:34 Pre-Increment ( temp int)
0:34 'ii' ( temp int)
0:2 Function Definition: PixelShaderFunction( ( temp void)
0:2 Function Parameters:
0:32 Branch: Return with expression
0:32 'input' ( in 4-component vector of float)
0:35 Function Call: f1(vf4; ( temp 4-component vector of float)
0:35 'input' ( in 4-component vector of float)
0:38 Test condition and select ( temp void)
0:38 Condition
0:38 Convert float to bool ( temp bool)
0:38 move second child to first child ( temp float)
0:38 'ii' ( temp float)
0:38 direct index ( temp float)
0:38 'input' ( in 4-component vector of float)
0:38 Constant:
0:38 2 (const int)
0:38 true case
0:39 Pre-Increment ( temp float)
0:39 'ii' ( temp float)
0:40 Pre-Increment ( temp int)
0:40 'ii' ( temp int)
0:41 Test condition and select ( temp void)
0:41 Condition
0:41 Compare Equal ( temp bool)
0:41 Convert int to float ( temp float)
0:41 'ii' ( temp int)
0:41 Constant:
0:41 1.000000
0:41 true case
0:42 Pre-Increment ( temp int)
0:42 'ii' ( temp int)
0:17 Function Definition: PixelShaderFunction( ( temp void)
0:17 Function Parameters:
0:? Sequence
0:2 move second child to first child ( temp 4-component vector of float)
0:17 move second child to first child ( temp 4-component vector of float)
0:? 'input' ( temp 4-component vector of float)
0:? 'input' (layout( location=0) in 4-component vector of float)
0:2 move second child to first child ( temp 4-component vector of float)
0:17 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:2 Function Call: @PixelShaderFunction(vf4; ( temp 4-component vector of float)
0:17 Function Call: @PixelShaderFunction(vf4; ( temp 4-component vector of float)
0:? 'input' ( temp 4-component vector of float)
0:? Linker Objects
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
@ -217,154 +241,178 @@ gl_FragCoord origin is upper left
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 103
// Id's are bound by 117
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "PixelShaderFunction" 96 99
EntryPoint Fragment 4 "PixelShaderFunction" 110 113
ExecutionMode 4 OriginUpperLeft
Source HLSL 500
Name 4 "PixelShaderFunction"
Name 11 "@PixelShaderFunction(vf4;"
Name 11 "f0(vf4;"
Name 10 "input"
Name 68 "ii"
Name 14 "f1(vf4;"
Name 13 "input"
Name 17 "@PixelShaderFunction(vf4;"
Name 16 "input"
Name 55 "param"
Name 78 "param"
Name 82 "ii"
Name 94 "input"
Name 96 "input"
Name 99 "@entryPointOutput"
Name 100 "param"
Decorate 96(input) Location 0
Decorate 99(@entryPointOutput) Location 0
Name 96 "ii"
Name 108 "input"
Name 110 "input"
Name 113 "@entryPointOutput"
Name 114 "param"
Decorate 110(input) Location 0
Decorate 113(@entryPointOutput) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypePointer Function 7(fvec4)
9: TypeFunction 7(fvec4) 8(ptr)
15: TypeBool
16: TypeVector 15(bool) 4
67: TypePointer Function 6(float)
69: TypeInt 32 0
70: 69(int) Constant 2
73: 6(float) Constant 0
78: 6(float) Constant 1065353216
80: TypeInt 32 1
81: TypePointer Function 80(int)
84: 80(int) Constant 1
95: TypePointer Input 7(fvec4)
96(input): 95(ptr) Variable Input
98: TypePointer Output 7(fvec4)
99(@entryPointOutput): 98(ptr) Variable Output
21: TypeBool
22: TypeVector 21(bool) 4
81: TypePointer Function 6(float)
83: TypeInt 32 0
84: 83(int) Constant 2
87: 6(float) Constant 0
92: 6(float) Constant 1065353216
94: TypeInt 32 1
95: TypePointer Function 94(int)
98: 94(int) Constant 1
109: TypePointer Input 7(fvec4)
110(input): 109(ptr) Variable Input
112: TypePointer Output 7(fvec4)
113(@entryPointOutput): 112(ptr) Variable Output
4(PixelShaderFunction): 2 Function None 3
5: Label
94(input): 8(ptr) Variable Function
100(param): 8(ptr) Variable Function
97: 7(fvec4) Load 96(input)
Store 94(input) 97
101: 7(fvec4) Load 94(input)
Store 100(param) 101
102: 7(fvec4) FunctionCall 11(@PixelShaderFunction(vf4;) 100(param)
Store 99(@entryPointOutput) 102
108(input): 8(ptr) Variable Function
114(param): 8(ptr) Variable Function
111: 7(fvec4) Load 110(input)
Store 108(input) 111
115: 7(fvec4) Load 108(input)
Store 114(param) 115
116: 7(fvec4) FunctionCall 17(@PixelShaderFunction(vf4;) 114(param)
Store 113(@entryPointOutput) 116
Return
FunctionEnd
11(@PixelShaderFunction(vf4;): 7(fvec4) Function None 9
11(f0(vf4;): 7(fvec4) Function None 9
10(input): 8(ptr) FunctionParameter
12: Label
68(ii): 67(ptr) Variable Function
19: 7(fvec4) Load 10(input)
20: 7(fvec4) Load 10(input)
23: 22(bvec4) FOrdEqual 19 20
24: 21(bool) All 23
SelectionMerge 26 None
BranchConditional 24 25 29
25: Label
27: 7(fvec4) Load 10(input)
ReturnValue 27
29: Label
30: 7(fvec4) Load 10(input)
31: 7(fvec4) FNegate 30
ReturnValue 31
26: Label
Unreachable
FunctionEnd
14(f1(vf4;): 7(fvec4) Function None 9
13(input): 8(ptr) FunctionParameter
15: Label
34: 7(fvec4) Load 13(input)
35: 7(fvec4) Load 13(input)
36: 22(bvec4) FOrdEqual 34 35
37: 21(bool) All 36
SelectionMerge 39 None
BranchConditional 37 38 42
38: Label
40: 7(fvec4) Load 13(input)
ReturnValue 40
42: Label
43: 7(fvec4) Load 13(input)
44: 7(fvec4) FNegate 43
ReturnValue 44
39: Label
Unreachable
FunctionEnd
17(@PixelShaderFunction(vf4;): 7(fvec4) Function None 9
16(input): 8(ptr) FunctionParameter
18: Label
55(param): 8(ptr) Variable Function
78(param): 8(ptr) Variable Function
82(ii): 81(ptr) Variable Function
13: 7(fvec4) Load 10(input)
14: 7(fvec4) Load 10(input)
17: 16(bvec4) FOrdEqual 13 14
18: 15(bool) All 17
SelectionMerge 20 None
BranchConditional 18 19 20
19: Label
21: 7(fvec4) Load 10(input)
ReturnValue 21
20: Label
23: 7(fvec4) Load 10(input)
24: 7(fvec4) Load 10(input)
25: 16(bvec4) FOrdEqual 23 24
26: 15(bool) All 25
SelectionMerge 28 None
BranchConditional 26 27 31
27: Label
29: 7(fvec4) Load 10(input)
ReturnValue 29
31: Label
32: 7(fvec4) Load 10(input)
33: 7(fvec4) FNegate 32
ReturnValue 33
28: Label
35: 7(fvec4) Load 10(input)
36: 7(fvec4) Load 10(input)
37: 16(bvec4) FOrdEqual 35 36
38: 15(bool) All 37
SelectionMerge 40 None
BranchConditional 38 39 40
39: Label
Branch 40
40: Label
41: 7(fvec4) Load 10(input)
42: 7(fvec4) Load 10(input)
43: 16(bvec4) FOrdEqual 41 42
44: 15(bool) All 43
SelectionMerge 46 None
BranchConditional 44 45 46
45: Label
Branch 46
46: Label
47: 7(fvec4) Load 10(input)
48: 7(fvec4) Load 10(input)
49: 16(bvec4) FOrdEqual 47 48
50: 15(bool) All 49
SelectionMerge 52 Flatten
96(ii): 95(ptr) Variable Function
47: 7(fvec4) Load 16(input)
48: 7(fvec4) Load 16(input)
49: 22(bvec4) FOrdEqual 47 48
50: 21(bool) All 49
SelectionMerge 52 None
BranchConditional 50 51 52
51: Label
53: 7(fvec4) Load 10(input)
53: 7(fvec4) Load 16(input)
ReturnValue 53
52: Label
55: 7(fvec4) Load 10(input)
56: 7(fvec4) Load 10(input)
57: 16(bvec4) FOrdEqual 55 56
58: 15(bool) All 57
SelectionMerge 60 None
BranchConditional 58 59 63
59: Label
61: 7(fvec4) Load 10(input)
ReturnValue 61
63: Label
64: 7(fvec4) Load 10(input)
65: 7(fvec4) FNegate 64
ReturnValue 65
60: Label
71: 67(ptr) AccessChain 10(input) 70
72: 6(float) Load 71
Store 68(ii) 72
74: 15(bool) FOrdNotEqual 72 73
SelectionMerge 76 None
BranchConditional 74 75 76
75: Label
77: 6(float) Load 68(ii)
79: 6(float) FAdd 77 78
Store 68(ii) 79
Branch 76
76: Label
83: 80(int) Load 82(ii)
85: 80(int) IAdd 83 84
Store 82(ii) 85
86: 80(int) Load 82(ii)
87: 6(float) ConvertSToF 86
88: 15(bool) FOrdEqual 87 78
56: 7(fvec4) Load 16(input)
Store 55(param) 56
57: 7(fvec4) FunctionCall 11(f0(vf4;) 55(param)
58: 7(fvec4) Load 16(input)
59: 7(fvec4) Load 16(input)
60: 22(bvec4) FOrdEqual 58 59
61: 21(bool) All 60
SelectionMerge 63 None
BranchConditional 61 62 63
62: Label
Branch 63
63: Label
64: 7(fvec4) Load 16(input)
65: 7(fvec4) Load 16(input)
66: 22(bvec4) FOrdEqual 64 65
67: 21(bool) All 66
SelectionMerge 69 None
BranchConditional 67 68 69
68: Label
Branch 69
69: Label
70: 7(fvec4) Load 16(input)
71: 7(fvec4) Load 16(input)
72: 22(bvec4) FOrdEqual 70 71
73: 21(bool) All 72
SelectionMerge 75 Flatten
BranchConditional 73 74 75
74: Label
76: 7(fvec4) Load 16(input)
ReturnValue 76
75: Label
79: 7(fvec4) Load 16(input)
Store 78(param) 79
80: 7(fvec4) FunctionCall 14(f1(vf4;) 78(param)
85: 81(ptr) AccessChain 16(input) 84
86: 6(float) Load 85
Store 82(ii) 86
88: 21(bool) FOrdNotEqual 86 87
SelectionMerge 90 None
BranchConditional 88 89 90
89: Label
91: 80(int) Load 82(ii)
92: 80(int) IAdd 91 84
Store 82(ii) 92
91: 6(float) Load 82(ii)
93: 6(float) FAdd 91 92
Store 82(ii) 93
Branch 90
90: Label
93: 7(fvec4) Undef
ReturnValue 93
97: 94(int) Load 96(ii)
99: 94(int) IAdd 97 98
Store 96(ii) 99
100: 94(int) Load 96(ii)
101: 6(float) ConvertSToF 100
102: 21(bool) FOrdEqual 101 92
SelectionMerge 104 None
BranchConditional 102 103 104
103: Label
105: 94(int) Load 96(ii)
106: 94(int) IAdd 105 98
Store 96(ii) 106
Branch 104
104: Label
107: 7(fvec4) Undef
ReturnValue 107
FunctionEnd

View File

@ -305,6 +305,5 @@ gl_FragCoord origin is upper left
66: 9(fvec4) CompositeConstruct 65 65 65 65
ReturnValue 66
45: Label
68: 9(fvec4) Undef
ReturnValue 68
Unreachable
FunctionEnd

View File

@ -344,6 +344,5 @@ gl_FragCoord origin is upper left
84: 9(fvec4) CompositeConstruct 83 83 83 83
ReturnValue 84
53: Label
86: 9(fvec4) Undef
ReturnValue 86
Unreachable
FunctionEnd

View File

@ -303,6 +303,5 @@ gl_FragCoord origin is upper left
66: 9(fvec4) CompositeConstruct 65 65 65 65
ReturnValue 66
45: Label
68: 9(fvec4) Undef
ReturnValue 68
Unreachable
FunctionEnd

View File

@ -118,6 +118,5 @@ gl_FragCoord origin is upper left
23: Label
ReturnValue 24
16: Label
26: 7(fvec4) Undef
ReturnValue 26
Unreachable
FunctionEnd

View File

@ -88,7 +88,7 @@ remap.similar_1a.everything.frag
22102: 649(ptr) Variable Function
24151: 12(int) Load 4408
13868: 9(bool) SGreaterThan 24151 2577
SelectionMerge 22309 None
SelectionMerge 14966 None
BranchConditional 13868 9492 17416
9492: Label
15624: 12(int) Load 4408
@ -109,7 +109,6 @@ remap.similar_1a.everything.frag
10505: 12(int) IAdd 11462 21176
14626: 13(float) ConvertSToF 10505
ReturnValue 14626
22309: Label
6429: 13(float) Undef
ReturnValue 6429
14966: Label
Unreachable
FunctionEnd

View File

@ -124,6 +124,5 @@ remap.similar_1a.none.frag
68: 8(float) ConvertSToF 67
ReturnValue 68
43: Label
70: 8(float) Undef
ReturnValue 70
Unreachable
FunctionEnd

View File

@ -93,7 +93,7 @@ remap.similar_1b.everything.frag
22102: 649(ptr) Variable Function
24151: 12(int) Load 4408
13868: 9(bool) SGreaterThan 24151 2577
SelectionMerge 22309 None
SelectionMerge 14966 None
BranchConditional 13868 10822 17416
10822: Label
22680: 12(int) Load 4408
@ -115,7 +115,6 @@ remap.similar_1b.everything.frag
10505: 12(int) IAdd 11462 21176
14626: 13(float) ConvertSToF 10505
ReturnValue 14626
22309: Label
6429: 13(float) Undef
ReturnValue 6429
14966: Label
Unreachable
FunctionEnd

View File

@ -130,6 +130,5 @@ remap.similar_1b.none.frag
73: 8(float) ConvertSToF 72
ReturnValue 73
46: Label
75: 8(float) Undef
ReturnValue 75
Unreachable
FunctionEnd

View File

@ -1,16 +1,16 @@
spv.controlFlowAttributes.frag
WARNING: 0:20: 'unroll' : expected no arguments
WARNING: 0:21: 'dont_unroll' : expected no arguments
WARNING: 0:22: 'dependency_infinite' : expected no arguments
WARNING: 0:23: 'dependency_length' : expected a single integer argument
WARNING: 0:24: '' : attribute with arguments not recognized, skipping
WARNING: 0:25: '' : attribute with arguments not recognized, skipping
WARNING: 0:26: '' : attribute with arguments not recognized, skipping
WARNING: 0:27: 'unroll' : expected no arguments
WARNING: 0:28: 'dont_unroll' : expected no arguments
WARNING: 0:29: 'dependency_infinite' : expected no arguments
WARNING: 0:30: 'dependency_length' : expected a single integer argument
WARNING: 0:31: '' : attribute with arguments not recognized, skipping
WARNING: 0:32: '' : attribute with arguments not recognized, skipping
WARNING: 0:33: '' : attribute with arguments not recognized, skipping
Validation failed
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 118
// Id's are bound by 123
Capability Shader
1: ExtInstImport "GLSL.std.450"
@ -20,220 +20,231 @@ Validation failed
Source GLSL 450
SourceExtension "GL_EXT_control_flow_attributes"
Name 4 "main"
Name 8 "i"
Name 36 "i"
Name 47 "cond"
Name 60 "i"
Name 79 "i"
Name 6 "f0("
Name 8 "f1("
Name 23 "i"
Name 41 "i"
Name 52 "cond"
Name 65 "i"
Name 84 "i"
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 0
16: 6(int) Constant 8
17: TypeBool
20: 6(int) Constant 1
31: 17(bool) ConstantTrue
46: TypePointer Private 17(bool)
47(cond): 46(ptr) Variable Private
54: 17(bool) ConstantFalse
55: 6(int) Constant 3
19: TypeBool
20: 19(bool) ConstantTrue
21: TypeInt 32 1
22: TypePointer Function 21(int)
24: 21(int) Constant 0
31: 21(int) Constant 8
34: 21(int) Constant 1
51: TypePointer Private 19(bool)
52(cond): 51(ptr) Variable Private
59: 19(bool) ConstantFalse
60: 21(int) Constant 3
4(main): 2 Function None 3
5: Label
8(i): 7(ptr) Variable Function
36(i): 7(ptr) Variable Function
60(i): 7(ptr) Variable Function
79(i): 7(ptr) Variable Function
Store 8(i) 9
Branch 10
10: Label
LoopMerge 12 13 Unroll
Branch 14
14: Label
15: 6(int) Load 8(i)
18: 17(bool) SLessThan 15 16
BranchConditional 18 11 12
11: Label
Branch 13
13: Label
19: 6(int) Load 8(i)
21: 6(int) IAdd 19 20
Store 8(i) 21
Branch 10
12: Label
Branch 22
22: Label
LoopMerge 24 25 DontUnroll
Branch 23
23: Label
23(i): 22(ptr) Variable Function
41(i): 22(ptr) Variable Function
65(i): 22(ptr) Variable Function
84(i): 22(ptr) Variable Function
Store 23(i) 24
Branch 25
25: Label
Branch 22
24: Label
Branch 26
26: Label
LoopMerge 28 29 DontUnroll
Branch 30
30: Label
BranchConditional 31 27 28
27: Label
Branch 29
29: Label
Branch 26
28: Label
Branch 32
32: Label
LoopMerge 34 35 DependencyInfinite
Branch 33
33: Label
Branch 35
35: Label
BranchConditional 31 32 34
34: Label
Store 36(i) 9
LoopMerge 27 28 Unroll
Branch 29
29: Label
30: 21(int) Load 23(i)
32: 19(bool) SLessThan 30 31
BranchConditional 32 26 27
26: Label
Branch 28
28: Label
33: 21(int) Load 23(i)
35: 21(int) IAdd 33 34
Store 23(i) 35
Branch 25
27: Label
36: 2 FunctionCall 6(f0()
Branch 37
37: Label
LoopMerge 39 40 DependencyLength 4
Branch 41
41: Label
42: 6(int) Load 36(i)
43: 17(bool) SLessThan 42 16
BranchConditional 43 38 39
38: Label
Branch 40
40: Label
44: 6(int) Load 36(i)
45: 6(int) IAdd 44 20
Store 36(i) 45
Branch 37
LoopMerge 39 40 DependencyInfinite
Branch 38
38: Label
Branch 40
40: Label
BranchConditional 20 37 39
39: Label
48: 17(bool) Load 47(cond)
SelectionMerge 50 Flatten
BranchConditional 48 49 50
49: Label
Branch 50
50: Label
51: 17(bool) Load 47(cond)
SelectionMerge 53 DontFlatten
BranchConditional 51 52 53
52: Label
Store 47(cond) 54
Branch 53
53: Label
SelectionMerge 57 DontFlatten
Switch 55 57
case 3: 56
56: Label
Branch 57
57: Label
Store 60(i) 9
Branch 61
61: Label
LoopMerge 63 64 None
Branch 65
65: Label
66: 6(int) Load 60(i)
67: 17(bool) SLessThan 66 16
BranchConditional 67 62 63
62: Label
Branch 64
64: Label
68: 6(int) Load 60(i)
69: 6(int) IAdd 68 20
Store 60(i) 69
Branch 61
63: Label
Store 41(i) 24
Branch 42
42: Label
LoopMerge 44 45 DependencyLength 4
Branch 46
46: Label
47: 21(int) Load 41(i)
48: 19(bool) SLessThan 47 31
BranchConditional 48 43 44
43: Label
Branch 45
45: Label
49: 21(int) Load 41(i)
50: 21(int) IAdd 49 34
Store 41(i) 50
Branch 42
44: Label
53: 19(bool) Load 52(cond)
SelectionMerge 55 Flatten
BranchConditional 53 54 55
54: Label
Branch 55
55: Label
56: 19(bool) Load 52(cond)
SelectionMerge 58 DontFlatten
BranchConditional 56 57 58
57: Label
Store 52(cond) 59
Branch 58
58: Label
SelectionMerge 62 DontFlatten
Switch 60 62
case 3: 61
61: Label
Branch 62
62: Label
Store 65(i) 24
Branch 66
66: Label
LoopMerge 68 69 None
Branch 70
70: Label
LoopMerge 72 73 None
Branch 74
74: Label
BranchConditional 31 71 72
71: Label
Branch 73
73: Label
Branch 70
72: Label
71: 21(int) Load 65(i)
72: 19(bool) SLessThan 71 31
BranchConditional 72 67 68
67: Label
Branch 69
69: Label
73: 21(int) Load 65(i)
74: 21(int) IAdd 73 34
Store 65(i) 74
Branch 66
68: Label
Branch 75
75: Label
LoopMerge 77 78 None
Branch 76
76: Label
Branch 78
78: Label
BranchConditional 31 75 77
Branch 79
79: Label
BranchConditional 20 76 77
76: Label
Branch 78
78: Label
Branch 75
77: Label
Store 79(i) 9
Branch 80
80: Label
LoopMerge 82 83 None
Branch 84
84: Label
85: 6(int) Load 79(i)
86: 17(bool) SLessThan 85 16
BranchConditional 86 81 82
81: Label
Branch 83
83: Label
87: 6(int) Load 79(i)
88: 6(int) IAdd 87 20
Store 79(i) 88
Branch 80
Branch 81
81: Label
Branch 83
83: Label
BranchConditional 20 80 82
82: Label
89: 17(bool) Load 47(cond)
SelectionMerge 91 None
BranchConditional 89 90 91
90: Label
Branch 91
91: Label
92: 17(bool) Load 47(cond)
SelectionMerge 94 None
BranchConditional 92 93 94
93: Label
Store 47(cond) 54
Branch 94
94: Label
Store 84(i) 24
Branch 85
85: Label
LoopMerge 87 88 None
Branch 89
89: Label
90: 21(int) Load 84(i)
91: 19(bool) SLessThan 90 31
BranchConditional 91 86 87
86: Label
Branch 88
88: Label
92: 21(int) Load 84(i)
93: 21(int) IAdd 92 34
Store 84(i) 93
Branch 85
87: Label
94: 19(bool) Load 52(cond)
SelectionMerge 96 None
Switch 55 96
case 3: 95
BranchConditional 94 95 96
95: Label
Branch 96
96: Label
Branch 99
99: Label
LoopMerge 101 102 Unroll DontUnroll DependencyLength 2
Branch 103
103: Label
104: 17(bool) Load 47(cond)
BranchConditional 104 100 101
100: Label
Branch 102
102: Label
97: 19(bool) Load 52(cond)
SelectionMerge 99 None
BranchConditional 97 98 99
98: Label
Store 52(cond) 59
Branch 99
99: Label
SelectionMerge 101 None
Switch 60 101
case 3: 100
100: Label
Branch 101
101: Label
SelectionMerge 106 DontFlatten
Switch 55 106
case 3: 105
Branch 104
104: Label
LoopMerge 106 107 Unroll DontUnroll DependencyLength 2
Branch 108
108: Label
109: 19(bool) Load 52(cond)
BranchConditional 109 105 106
105: Label
Branch 106
Branch 107
107: Label
Branch 104
106: Label
109: 17(bool) Load 47(cond)
SelectionMerge 111 Flatten
BranchConditional 109 110 111
SelectionMerge 111 DontFlatten
Switch 60 111
case 3: 110
110: Label
Branch 111
111: Label
Branch 112
112: Label
LoopMerge 114 115 DependencyInfinite
Branch 116
116: Label
117: 17(bool) Load 47(cond)
BranchConditional 117 113 114
113: Label
Branch 115
114: 19(bool) Load 52(cond)
SelectionMerge 116 Flatten
BranchConditional 114 115 116
115: Label
Branch 112
114: Label
Branch 116
116: Label
Branch 117
117: Label
LoopMerge 119 120 DependencyInfinite
Branch 121
121: Label
122: 19(bool) Load 52(cond)
BranchConditional 122 118 119
118: Label
Branch 120
120: Label
Branch 117
119: Label
Return
FunctionEnd
6(f0(): 2 Function None 3
7: Label
Branch 10
10: Label
LoopMerge 12 13 DontUnroll
Branch 11
11: Label
Branch 13
13: Label
Branch 10
12: Label
Unreachable
FunctionEnd
8(f1(): 2 Function None 3
9: Label
Branch 14
14: Label
LoopMerge 16 17 DontUnroll
Branch 18
18: Label
BranchConditional 20 15 16
15: Label
Branch 17
17: Label
Branch 14
16: Label
Return
FunctionEnd

View File

@ -0,0 +1,54 @@
spv.dead-after-continue.vert
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 29
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 20 28
Source GLSL 450
Name 4 "main"
Name 8 "i"
Name 20 "o"
Name 28 "c"
Decorate 20(o) Location 0
Decorate 28(c) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 0
16: 6(int) Constant 5
17: TypeBool
19: TypePointer Output 6(int)
20(o): 19(ptr) Variable Output
21: 6(int) Constant 1
23: 6(int) Constant 2
26: 6(int) Constant 3
27: TypePointer Input 6(int)
28(c): 27(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
LoopMerge 12 13 None
Branch 14
14: Label
15: 6(int) Load 8(i)
18: 17(bool) SLessThan 15 16
BranchConditional 18 11 12
11: Label
Store 20(o) 21
Branch 13
13: Label
24: 6(int) Load 8(i)
25: 6(int) IAdd 24 21
Store 8(i) 25
Branch 10
12: Label
Store 20(o) 26
Return
FunctionEnd

View File

@ -0,0 +1,31 @@
spv.dead-after-discard.frag
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 15
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 8 14
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
Name 4 "main"
Name 8 "o"
Name 14 "c"
Decorate 8(o) Location 0
Decorate 14(c) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Output 6(int)
8(o): 7(ptr) Variable Output
9: 6(int) Constant 1
11: 6(int) Constant 3
12: TypeFloat 32
13: TypePointer Input 12(float)
14(c): 13(ptr) Variable Input
4(main): 2 Function None 3
5: Label
Store 8(o) 9
Kill
FunctionEnd

View File

@ -0,0 +1,67 @@
spv.dead-after-loop-break.vert
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 36
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 8 25
Source GLSL 450
Name 4 "main"
Name 8 "o"
Name 11 "i"
Name 25 "c"
Decorate 8(o) Location 0
Decorate 25(c) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Output 6(int)
8(o): 7(ptr) Variable Output
9: 6(int) Constant 1
10: TypePointer Function 6(int)
12: 6(int) Constant 0
19: 6(int) Constant 5
20: TypeBool
22: 6(int) Constant 2
24: TypePointer Input 6(int)
25(c): 24(ptr) Variable Input
30: 6(int) Constant 3
32: 6(int) Constant 4
35: 6(int) Constant 6
4(main): 2 Function None 3
5: Label
11(i): 10(ptr) Variable Function
Store 8(o) 9
Store 11(i) 12
Branch 13
13: Label
LoopMerge 15 16 None
Branch 17
17: Label
18: 6(int) Load 11(i)
21: 20(bool) SLessThan 18 19
BranchConditional 21 14 15
14: Label
Store 8(o) 22
23: 6(int) Load 11(i)
26: 6(int) Load 25(c)
27: 20(bool) IEqual 23 26
SelectionMerge 29 None
BranchConditional 27 28 29
28: Label
Store 8(o) 30
Branch 15
29: Label
Store 8(o) 19
Branch 16
16: Label
33: 6(int) Load 11(i)
34: 6(int) IAdd 33 9
Store 11(i) 34
Branch 13
15: Label
Store 8(o) 35
Return
FunctionEnd

View File

@ -0,0 +1,29 @@
spv.dead-after-return.vert
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 14
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 8 13
Source GLSL 450
Name 4 "main"
Name 8 "o"
Name 13 "c"
Decorate 8(o) Location 0
Decorate 13(c) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Output 6(int)
8(o): 7(ptr) Variable Output
9: 6(int) Constant 1
11: 6(int) Constant 3
12: TypePointer Input 6(int)
13(c): 12(ptr) Variable Input
4(main): 2 Function None 3
5: Label
Store 8(o) 9
Return
FunctionEnd

View File

@ -0,0 +1,40 @@
spv.dead-after-switch-break.vert
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 21
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 8 14
Source GLSL 450
Name 4 "main"
Name 8 "c"
Name 14 "o"
Decorate 8(c) Location 0
Decorate 14(o) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Input 6(int)
8(c): 7(ptr) Variable Input
13: TypePointer Output 6(int)
14(o): 13(ptr) Variable Output
15: 6(int) Constant 1
17: 6(int) Constant 2
20: 6(int) Constant 3
4(main): 2 Function None 3
5: Label
9: 6(int) Load 8(c)
SelectionMerge 12 None
Switch 9 11
case 0: 10
11: Label
Branch 12
10: Label
Store 14(o) 15
Branch 12
12: Label
Store 14(o) 20
Return
FunctionEnd

View File

@ -0,0 +1,55 @@
spv.dead-complex-continue-after-return.vert
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 31
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 11 30
Source GLSL 450
Name 4 "main"
Name 8 "i"
Name 11 "o"
Name 30 "c"
Decorate 11(o) Location 0
Decorate 30(c) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 0
10: TypePointer Output 6(int)
11(o): 10(ptr) Variable Output
12: 6(int) Constant 1
19: 6(int) Constant 5
20: TypeBool
22: 6(int) Constant 2
24: 6(int) Constant 3
27: 6(int) Constant 99
28: 6(int) Constant 4
29: TypePointer Input 6(int)
30(c): 29(ptr) Variable Input
4(main): 2 Function None 3
5: Label
8(i): 7(ptr) Variable Function
Store 8(i) 9
Store 11(o) 12
Store 8(i) 9
Branch 13
13: Label
LoopMerge 15 16 None
Branch 17
17: Label
18: 6(int) Load 8(i)
21: 20(bool) SLessThan 18 19
BranchConditional 21 14 15
14: Label
Store 11(o) 22
Return
16: Label
Branch 13
15: Label
Store 11(o) 28
Return
FunctionEnd

View File

@ -0,0 +1,51 @@
spv.dead-complex-merge-after-return.vert
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 36
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 11 27
Source GLSL 450
Name 4 "main"
Name 8 "i"
Name 11 "o"
Name 27 "c"
Decorate 11(o) Location 0
Decorate 27(c) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 0
10: TypePointer Output 6(int)
11(o): 10(ptr) Variable Output
12: 6(int) Constant 1
17: 6(int) Constant 2
19: 6(int) Constant 3
22: 6(int) Constant 5
23: TypeBool
25: 6(int) Constant 4
26: TypePointer Input 6(int)
27(c): 26(ptr) Variable Input
32: 6(int) Constant 100
34: 6(int) Constant 200
35: 6(int) Constant 300
4(main): 2 Function None 3
5: Label
8(i): 7(ptr) Variable Function
Store 8(i) 9
Store 11(o) 12
Branch 13
13: Label
LoopMerge 15 16 None
Branch 14
14: Label
Store 11(o) 17
Return
16: Label
Branch 13
15: Label
Unreachable
FunctionEnd

View File

@ -160,7 +160,7 @@ spv.earlyReturnDiscard.frag
102: Label
Return
100: Label
Branch 67
Unreachable
67: Label
106: 7(fvec4) Load 9(color)
107: 7(fvec4) Load 13(color2)

View File

@ -38,5 +38,5 @@ spv.for-notest.vert
Store 8(i) 19
Branch 10
12: Label
Return
Unreachable
FunctionEnd

View File

@ -99,8 +99,7 @@ spv.forwardFun.frag
45: Label
ReturnValue 46
42: Label
48: 8(float) Undef
ReturnValue 48
Unreachable
FunctionEnd
16(foo(vf4;): 8(float) Function None 14
15(bar): 13(ptr) FunctionParameter

View File

@ -105,8 +105,7 @@ WARNING: 0:5: varying deprecated in version 130; may be removed in future releas
44: Label
ReturnValue 45
41: Label
47: 6(float) Undef
ReturnValue 47
Unreachable
FunctionEnd
18(missingReturn(): 6(float) Function None 15
19: Label

View File

@ -37,5 +37,5 @@ spv.merge-unreachable.frag
23: Label
Return
21: Label
Return
Unreachable
FunctionEnd

View File

@ -1,9 +1,29 @@
void f0() {
[unroll] do {} while (false);
}
void f1() {
[unroll] do {;} while (false);
}
float f2(float input) {
do { return (float4)input; } while (input > 2.0);
}
void f3(float input) {
do ++input; while (input < 10.0);
}
void f4(float input) {
do while (++input < 10.0); while (++input < 10.0); // nest while inside do-while
}
float4 PixelShaderFunction(float input) : COLOR0
{
[unroll] do {} while (false);
[unroll] do {;} while (false);
do { return (float4)input; } while (input > 2.0);
do ++input; while (input < 10.0);
do while (++input < 10.0); while (++input < 10.0); // nest while inside do-while
f0();
f1();
f2(input);
f3(input);
f4(input);
return (float4)input;
}

View File

@ -1,17 +1,59 @@
void f0() {
for (;;) ;
}
void f1(float4 input) {
for (++input; ; ) ;
}
void f2(float4 input) {
[unroll] for (; any(input != input); ) {}
}
float f3(float4 input) {
for (; any(input != input); ) { return -input; }
}
float f4(float4 input) {
for (--input; any(input != input); input += 2) { return -input; }
}
void f5(float4 input) {
for (;;) if (input.x > 2.0) break;
}
void f6(float4 input) {
for (;;) if (input.x > 2.0) continue;
}
void f99() {
for (int first = 0, second = 1; ;) first + second;
}
void f100(float ii) {
for (--ii, --ii, --ii;;) ii;
}
float4 PixelShaderFunction(float4 input) : COLOR0
{
for (;;) ;
for (++input; ; ) ;
[unroll] for (; any(input != input); ) {}
for (; any(input != input); ) { return -input; }
for (--input; any(input != input); input += 2) { return -input; }
for (;;) if (input.x > 2.0) break;
for (;;) if (input.x > 2.0) continue;
f0();
f1(input);
f2(input);
f3(input);
f4(input);
f5(input);
f6(input);
float ii;
for (int ii = -1; ii < 3; ++ii) if (ii == 2) continue;
--ii;
for (int first = 0, second = 1; ;) first + second;
f99();
for ( int i = 0, count = int(ii); i < count; i++ );
for (float first = 0, second[2], third; first < second[0]; ++second[1]) first + second[1] + third;
for (--ii, --ii, --ii;;) ii;
f100(ii);
return input;
}

View File

@ -1,12 +1,24 @@
float4 f0(float4 input) {
if (all(input == input))
return input;
else
return -input;
}
float4 f1(float4 input) {
if (all(input == input)) {
return input;
} else {
return -input;
}
}
float4 PixelShaderFunction(float4 input) : COLOR0
{
if (all(input == input))
return input;
if (all(input == input))
return input;
else
return -input;
f0(input);
if (all(input == input))
;
@ -20,11 +32,7 @@ float4 PixelShaderFunction(float4 input) : COLOR0
return input;
}
if (all(input == input)) {
return input;
} else {
return -input;
}
f1(input);
int ii;
if (float ii = input.z)

View File

@ -4,11 +4,18 @@
bool cond;
void f0() {
[[loop]] for (;;) { }
}
void f1() {
[[dont_unroll]] while(true) { }
}
void main()
{
[[unroll]] for (int i = 0; i < 8; ++i) { }
[[loop]] for (;;) { }
[[dont_unroll]] while(true) { }
f0();
[[dependency_infinite]] do { } while(true);
[[dependency_length(1+3)]] for (int i = 0; i < 8; ++i) { }
[[flatten]] if (cond) { } else { }

View File

@ -0,0 +1,14 @@
#version 450
layout(location =0 ) in int c;
layout(location =0 ) out int o;
void main() {
int i;
for (i=0; i < 5; i++) {
o = 1;
continue;
o = 2;
}
o = 3;
}

View File

@ -0,0 +1,10 @@
#version 450
layout(location =0 ) in float c;
layout(location =0 ) out int o;
void main() {
o = 1;
discard;
o = 3;
}

View File

@ -0,0 +1,19 @@
#version 450
layout(location =0 ) in int c;
layout(location =0 ) out int o;
void main() {
int i;
o = 1;
for (i=0; i < 5; i++) {
o = 2;
if (i==c) {
o = 3;
break;
o = 4;
}
o = 5;
}
o = 6;
}

View File

@ -0,0 +1,10 @@
#version 450
layout(location =0 ) in int c;
layout(location =0 ) out int o;
void main() {
o = 1;
return;
o = 3;
}

View File

@ -0,0 +1,15 @@
#version 450
layout(location =0 ) in int c;
layout(location =0 ) out int o;
void main() {
int i;
switch(c) {
case 0: o=1;
break;
o=2;
default: break;
}
o = 3;
}

View File

@ -0,0 +1,19 @@
#version 450
layout(location =0 ) in int c;
layout(location =0 ) out int o;
void main() {
int i = 0;
o = 1;
// This has non-trivial continue target.
for (i=0; i < 5; ++i, o=99) {
o = 2;
return;
o = 3;
}
// This is considered reachable since Glslang codegen will
// create a conditional branch in the header, and one arm
// of that branch reaches this merge block.
o = 4;
}

View File

@ -0,0 +1,23 @@
#version 450
layout(location =0 ) in int c;
layout(location =0 ) out int o;
void main() {
int i = 0;
o = 1;
do {
o = 2;
return;
o = 3;
} while(i++ < 5);
// All this is a dead merge block.
o = 4;
if (c==4) {
o = 100;
} else {
o = 200;
}
o = 300;
}

View File

@ -63,6 +63,7 @@ std::string FileNameAsCustomTestSuffixIoMap(
}
using CompileVulkanToSpirvTest = GlslangTest<::testing::TestWithParam<std::string>>;
using CompileVulkanToSpirvDeadCodeElimTest = GlslangTest<::testing::TestWithParam<std::string>>;
using CompileVulkanToDebugSpirvTest = GlslangTest<::testing::TestWithParam<std::string>>;
using CompileVulkan1_1ToSpirvTest = GlslangTest<::testing::TestWithParam<std::string>>;
using CompileToSpirv14Test = GlslangTest<::testing::TestWithParam<std::string>>;
@ -85,6 +86,13 @@ TEST_P(CompileVulkanToSpirvTest, FromFile)
Target::Spv);
}
TEST_P(CompileVulkanToSpirvDeadCodeElimTest, FromFile)
{
loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(),
Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0,
Target::Spv);
}
// Compiling GLSL to SPIR-V with debug info under Vulkan semantics. Expected
// to successfully generate SPIR-V.
TEST_P(CompileVulkanToDebugSpirvTest, FromFile)
@ -417,6 +425,23 @@ INSTANTIATE_TEST_CASE_P(
FileNameAsCustomTestSuffix
);
// Cases with deliberately unreachable code.
// By default the compiler will aggressively eliminate
// unreachable merges and continues.
INSTANTIATE_TEST_CASE_P(
GlslWithDeadCode, CompileVulkanToSpirvDeadCodeElimTest,
::testing::ValuesIn(std::vector<std::string>({
"spv.dead-after-continue.vert",
"spv.dead-after-discard.frag",
"spv.dead-after-return.vert",
"spv.dead-after-loop-break.vert",
"spv.dead-after-switch-break.vert",
"spv.dead-complex-continue-after-return.vert",
"spv.dead-complex-merge-after-return.vert",
})),
FileNameAsCustomTestSuffix
);
// clang-format off
INSTANTIATE_TEST_CASE_P(
Glsl, CompileVulkanToDebugSpirvTest,

View File

@ -113,7 +113,7 @@ public:
forceVersionProfile(false),
isForwardCompatible(false) {
// Perform validation by default.
validatorOptions.validate = true;
spirvOptions.validate = true;
}
// Tries to load the contents from the file at the given |path|. On success,
@ -693,14 +693,14 @@ public:
expectedOutputFname, result.spirvWarningsErrors);
}
glslang::SpvOptions& options() { return validatorOptions; }
glslang::SpvOptions& options() { return spirvOptions; }
private:
const int defaultVersion;
const EProfile defaultProfile;
const bool forceVersionProfile;
const bool isForwardCompatible;
glslang::SpvOptions validatorOptions;
glslang::SpvOptions spirvOptions;
};
} // namespace glslangtest