Generate correctly structured do-while loops.

The loop test is always emitted before the loop body.

For do-while loops, use a phi node to track whether we're
on the first loop iteration, and only check the loop test
on the second and subsequent iterations.

For do-while loops, the loop test branch no longer occurs
at the top of the loop, so it must get its own selection
merge instruction.

A block can't be the target of more than one merge instruction.
So when the loop test executes after the body (as in do-while in GLSL)
we need to introduce a dummy block to be the target of the selection
merge just before the loop test conditional branch.

The other arm of the branch exits the loop and hence is the
"break block" exception in the structured control flow rules.
This commit is contained in:
David Neto 2015-07-15 16:21:26 -04:00
parent 51b31b5785
commit c22f37cfb4
8 changed files with 1486 additions and 1373 deletions

View File

@ -1147,28 +1147,18 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
// body emission needs to know what the for-loop terminal is when it sees a "continue" // body emission needs to know what the for-loop terminal is when it sees a "continue"
loopTerminal.push(node->getTerminal()); loopTerminal.push(node->getTerminal());
builder.makeNewLoop(); builder.makeNewLoop(node->testFirst());
bool bodyOut = false;
if (! node->testFirst()) {
builder.endLoopHeaderWithoutTest();
if (node->getBody()) {
breakForLoop.push(true);
node->getBody()->traverse(this);
breakForLoop.pop();
}
bodyOut = true;
builder.createBranchToLoopTest();
}
if (node->getTest()) { if (node->getTest()) {
node->getTest()->traverse(this); node->getTest()->traverse(this);
// the AST only contained the test computation, not the branch, we have to add it // the AST only contained the test computation, not the branch, we have to add it
spv::Id condition = builder.accessChainLoad(TranslatePrecisionDecoration(node->getTest()->getType())); spv::Id condition = builder.accessChainLoad(TranslatePrecisionDecoration(node->getTest()->getType()));
builder.createLoopTestBranch(condition); builder.createLoopTestBranch(condition);
} else {
builder.createBranchToBody();
} }
if (! bodyOut && node->getBody()) { if (node->getBody()) {
breakForLoop.push(true); breakForLoop.push(true);
node->getBody()->traverse(this); node->getBody()->traverse(this);
breakForLoop.pop(); breakForLoop.pop();

View File

@ -1736,16 +1736,29 @@ void Builder::endSwitch(std::vector<Block*>& /*segmentBlock*/)
} }
// Comments in header // Comments in header
void Builder::makeNewLoop() void Builder::makeNewLoop(bool loopTestFirst)
{ {
Loop loop = { }; loops.push({ });
Loop& loop = loops.top();
loop.function = &getBuildPoint()->getParent(); loop.function = &getBuildPoint()->getParent();
loop.header = new Block(getUniqueId(), *loop.function); loop.header = new Block(getUniqueId(), *loop.function);
loop.merge = new Block(getUniqueId(), *loop.function); loop.merge = new Block(getUniqueId(), *loop.function);
loop.test = NULL; // Delaying creation of the loop body perturbs test results less,
// which makes for easier patch review.
// TODO(dneto): Create the loop body block here, instead of
// upon first use.
loop.body = 0;
loop.testFirst = loopTestFirst;
loop.isFirstIteration = 0;
loops.push(loop); // The loop test is always emitted before the loop body.
// But if the loop test executes at the bottom of the loop, then
// execute the test only on the second and subsequent iterations.
// Remember the block that branches to the loop header. This
// is required for the test-after-body case.
Block* preheader = getBuildPoint();
// Branch into the loop // Branch into the loop
createBranch(loop.header); createBranch(loop.header);
@ -1753,56 +1766,95 @@ void Builder::makeNewLoop()
// Set ourselves inside the loop // Set ourselves inside the loop
loop.function->addBlock(loop.header); loop.function->addBlock(loop.header);
setBuildPoint(loop.header); setBuildPoint(loop.header);
if (!loopTestFirst) {
// Generate code to defer the loop test until the second and
// subsequent iterations.
// A phi node determines whether we're on the first iteration.
loop.isFirstIteration = new Instruction(getUniqueId(), makeBoolType(), OpPhi);
// It's always the first iteration when coming from the preheader.
// All other branches to this loop header will need to indicate "false",
// but we don't yet know where they will come from.
loop.isFirstIteration->addIdOperand(makeBoolConstant(true));
loop.isFirstIteration->addIdOperand(preheader->getId());
getBuildPoint()->addInstruction(loop.isFirstIteration);
// Mark the end of the structured loop. This must exist in the loop header block.
createMerge(OpLoopMerge, loop.merge, LoopControlMaskNone);
// Generate code to see if this is the first iteration of the loop.
// It needs to be in its own block, since the loop merge and
// the selection merge instructions can't both be in the same
// (header) block.
Block* firstIterationCheck = new Block(getUniqueId(), *loop.function);
createBranch(firstIterationCheck);
loop.function->addBlock(firstIterationCheck);
setBuildPoint(firstIterationCheck);
loop.body = new Block(getUniqueId(), *loop.function);
// Control flow after this "if" normally reconverges at the loop body.
// However, the loop test has a "break branch" out of this selection
// construct because it can transfer control to the loop merge block.
createMerge(OpSelectionMerge, loop.body, SelectionControlMaskNone);
Block* loopTest = new Block(getUniqueId(), *loop.function);
createConditionalBranch(loop.isFirstIteration->getResultId(), loop.body, loopTest);
loop.function->addBlock(loopTest);
setBuildPoint(loopTest);
}
} }
void Builder::createLoopTestBranch(Id condition) void Builder::createLoopTestBranch(Id condition)
{ {
Loop& loop = loops.top(); Loop& loop = loops.top();
// If loop.test exists, then we've already generated the LoopMerge // Generate the merge instruction. If the loop test executes before
// for this loop. // the body, then this is a loop merge. Otherwise the loop merge
if (!loop.test) // has already been generated and this is a conditional merge.
createMerge(OpLoopMerge, loop.merge, LoopControlMaskNone); if (loop.testFirst) {
createMerge(OpLoopMerge, loop.merge, LoopControlMaskNone);
loop.body = new Block(getUniqueId(), *loop.function);
// Branching to the "body" block will keep control inside
// the loop.
createConditionalBranch(condition, loop.body, loop.merge);
loop.function->addBlock(loop.body);
setBuildPoint(loop.body);
} else {
// The branch to the loop merge block is the allowed exception
// to the structured control flow. Otherwise, control flow will
// continue to loop.body block. Since that is already the target
// of a merge instruction, and a block can't be the target of more
// than one merge instruction, we need to make an intermediate block.
Block* stayInLoopBlock = new Block(getUniqueId(), *loop.function);
createMerge(OpSelectionMerge, stayInLoopBlock, SelectionControlMaskNone);
// Branching to the "body" block will keep control inside // This is the loop test.
// the loop. createConditionalBranch(condition, stayInLoopBlock, loop.merge);
Block* body = new Block(getUniqueId(), *loop.function);
createConditionalBranch(condition, body, loop.merge); // The dummy block just branches to the real loop body.
loop.function->addBlock(body); loop.function->addBlock(stayInLoopBlock);
setBuildPoint(body); setBuildPoint(stayInLoopBlock);
createBranchToBody();
}
} }
void Builder::endLoopHeaderWithoutTest() void Builder::createBranchToBody()
{ {
Loop& loop = loops.top(); Loop& loop = loops.top();
assert(loop.body);
createMerge(OpLoopMerge, loop.merge, LoopControlMaskNone); // This is a reconvergence of control flow, so no merge instruction
Block* body = new Block(getUniqueId(), *loop.function); // is required.
createBranch(body); createBranch(loop.body);
loop.function->addBlock(body); loop.function->addBlock(loop.body);
setBuildPoint(body); setBuildPoint(loop.body);
assert(!loop.test);
loop.test = new Block(getUniqueId(), *loop.function);
}
void Builder::createBranchToLoopTest()
{
Loop& loop = loops.top();
Block* testBlock = loop.test;
assert(testBlock);
createBranch(testBlock);
loop.function->addBlock(testBlock);
setBuildPoint(testBlock);
} }
void Builder::createLoopContinue() void Builder::createLoopContinue()
{ {
Loop& loop = loops.top(); createBranchToLoopHeaderFromInside(loops.top());
if (loop.test)
createBranch(loop.test);
else
createBranch(loop.header);
// Set up a block for dead code. // Set up a block for dead code.
createAndSetNoPredecessorBlock("post-loop-continue"); createAndSetNoPredecessorBlock("post-loop-continue");
} }
@ -1821,7 +1873,7 @@ void Builder::closeLoop()
Loop& loop = loops.top(); Loop& loop = loops.top();
// Branch back to the top // Branch back to the top
createBranch(loop.header); createBranchToLoopHeaderFromInside(loop);
// Add the merge block and set the build point to it // Add the merge block and set the build point to it
loop.function->addBlock(loop.merge); loop.function->addBlock(loop.merge);
@ -1830,6 +1882,18 @@ void Builder::closeLoop()
loops.pop(); loops.pop();
} }
// Create a branch to the header of the given loop, from inside
// the loop body.
// Adjusts the phi node for the first-iteration value if needeed.
void Builder::createBranchToLoopHeaderFromInside(const Loop& loop)
{
createBranch(loop.header);
if (loop.isFirstIteration) {
loop.isFirstIteration->addIdOperand(makeBoolConstant(false));
loop.isFirstIteration->addIdOperand(getBuildPoint()->getId());
}
}
void Builder::clearAccessChain() void Builder::clearAccessChain()
{ {
accessChain.base = 0; accessChain.base = 0;

View File

@ -357,35 +357,25 @@ public:
// Finish off the innermost switch. // Finish off the innermost switch.
void endSwitch(std::vector<Block*>& segmentBB); void endSwitch(std::vector<Block*>& segmentBB);
// Start the beginning of a new loop. // Start the beginning of a new loop, and prepare the builder to
void makeNewLoop(); // generate code for the loop test.
// The loopTestFirst parameter is true when the loop test executes before
// the body. (It is false for do-while loops.)
void makeNewLoop(bool loopTestFirst);
// Add the branch for the loop test, based on the given condition. // Add the branch for the loop test, based on the given condition.
// The true branch goes to the block that remains inside the loop, and // The true branch goes to the first block in the loop body, and
// the false branch goes to the loop's merge block. The builder insertion // the false branch goes to the loop's merge block. The builder insertion
// point will be placed at the start of the inside-the-loop block. // point will be placed at the start of the body.
void createLoopTestBranch(Id condition); void createLoopTestBranch(Id condition);
// Finish generating the loop header block in the case where the loop test // Generate an unconditional branch to the loop body. The builder insertion
// is at the bottom of the loop. It will include the LoopMerge instruction // point will be placed at the start of the body. Use this when there is
// and a branch to the rest of the body. The loop header block must be // no loop test.
// separate from the rest of the body to make room for the the two kinds void createBranchToBody();
// of *Merge instructions that might have to occur just before a branch:
// the loop header must have a LoopMerge as its second-last instruction,
// and the body might begin with a conditional branch, which must have its
// own SelectionMerge instruction.
// Also create the basic block that will contain the loop test, but don't
// insert it into the function yet. Any "continue" constructs in this loop
// will branch to the loop test block. The builder insertion point will be
// placed at the start of the body block.
void endLoopHeaderWithoutTest();
// Generate a branch to the loop test block. This can only be called if
// the loop test is at the bottom of the loop. The builder insertion point
// is left at the start of the test block.
void createBranchToLoopTest();
// Add a branch to the test of the current (innermost) loop. // Add a branch to the test of the current (innermost) loop.
// The way we generate code, that's also the loop header.
void createLoopContinue(); void createLoopContinue();
// Add an exit (e.g. "break") for the innermost loop that you're in // Add an exit (e.g. "break") for the innermost loop that you're in
@ -499,6 +489,9 @@ protected:
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock); void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
void dumpInstructions(std::vector<unsigned int>&, const std::vector<Instruction*>&) const; void dumpInstructions(std::vector<unsigned int>&, const std::vector<Instruction*>&) const;
struct Loop; // Defined below.
void createBranchToLoopHeaderFromInside(const Loop& loop);
SourceLanguage source; SourceLanguage source;
int sourceVersion; int sourceVersion;
std::vector<const char*> extensions; std::vector<const char*> extensions;
@ -543,11 +536,18 @@ protected:
// to the merge block when either the loop test fails, or when a // to the merge block when either the loop test fails, or when a
// nested "break" is encountered. // nested "break" is encountered.
Block* merge; Block* merge;
// If not NULL, the test block is the basic block containing the loop // The body block is the first basic block in the body of the loop, i.e.
// test and the conditional branch back to the header or the merge // the code that is to be repeatedly executed, aside from loop control.
// block. This is created for "do-while" loops, and is the target of // This member is null until we generate code that references the loop
// any "continue" constructs that might exist. // body block.
Block* test; Block* body;
// True when the loop test executes before the body.
bool testFirst;
// When the test executes after the body, this is defined as the phi
// instruction that tells us whether we are on the first iteration of
// the loop. Otherwise this is null.
Instruction* isFirstIteration;
// The function containing the loop.
Function* function; Function* function;
}; };

View File

@ -5,7 +5,7 @@ Linked vertex stage:
// Module Version 99 // Module Version 99
// Generated by (magic number): 51a00bb // Generated by (magic number): 51a00bb
// Id's are bound by 26 // Id's are bound by 30
Source ESSL 300 Source ESSL 300
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
@ -13,45 +13,52 @@ Linked vertex stage:
EntryPoint Vertex 4 EntryPoint Vertex 4
Name 4 "main" Name 4 "main"
Name 9 "i" Name 9 "i"
Name 24 "gl_VertexID" Name 28 "gl_VertexID"
Name 25 "gl_InstanceID" Name 29 "gl_InstanceID"
Decorate 9(i) PrecisionHigh Decorate 9(i) PrecisionHigh
Decorate 24(gl_VertexID) PrecisionHigh Decorate 28(gl_VertexID) PrecisionHigh
Decorate 24(gl_VertexID) BuiltIn VertexId Decorate 28(gl_VertexID) BuiltIn VertexId
Decorate 24(gl_VertexID) NoStaticUse Decorate 28(gl_VertexID) NoStaticUse
Decorate 25(gl_InstanceID) PrecisionHigh Decorate 29(gl_InstanceID) PrecisionHigh
Decorate 25(gl_InstanceID) BuiltIn InstanceId Decorate 29(gl_InstanceID) BuiltIn InstanceId
Decorate 25(gl_InstanceID) NoStaticUse Decorate 29(gl_InstanceID) NoStaticUse
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
7: TypeInt 32 1 7: TypeInt 32 1
8: TypePointer Function 7(int) 8: TypePointer Function 7(int)
10: 7(int) Constant 0 10: 7(int) Constant 0
16: 7(int) Constant 1 14: TypeBool
19: 7(int) Constant 10 15: 14(bool) ConstantTrue
20: TypeBool 20: 7(int) Constant 10
23: TypePointer Input 7(int) 24: 7(int) Constant 1
24(gl_VertexID): 23(ptr) Variable Input 26: 14(bool) ConstantFalse
25(gl_InstanceID): 23(ptr) Variable Input 27: TypePointer Input 7(int)
28(gl_VertexID): 27(ptr) Variable Input
29(gl_InstanceID): 27(ptr) Variable Input
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
9(i): 8(ptr) Variable Function 9(i): 8(ptr) Variable Function
Store 9(i) 10 Store 9(i) 10
Branch 11 Branch 11
11: Label 11: Label
13: 14(bool) Phi 15 5 26 17
LoopMerge 12 None LoopMerge 12 None
Branch 13 Branch 16
13: Label 16: Label
15: 7(int) Load 9(i) SelectionMerge 17 None
17: 7(int) IAdd 15 16 BranchConditional 13 17 18
Store 9(i) 17 18: Label
Branch 14 19: 7(int) Load 9(i)
14: Label 21: 14(bool) SLessThan 19 20
18: 7(int) Load 9(i) SelectionMerge 22 None
21: 20(bool) SLessThan 18 19 BranchConditional 21 22 12
BranchConditional 21 22 12
22: Label 22: Label
Branch 11 Branch 17
17: Label
23: 7(int) Load 9(i)
25: 7(int) IAdd 23 24
Store 9(i) 25
Branch 11
12: Label 12: Label
Branch 6 Branch 6
6: Label 6: Label

View File

@ -5,7 +5,7 @@ Linked vertex stage:
// Module Version 99 // Module Version 99
// Generated by (magic number): 51a00bb // Generated by (magic number): 51a00bb
// Id's are bound by 48 // Id's are bound by 52
Source ESSL 300 Source ESSL 300
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
@ -13,97 +13,104 @@ Linked vertex stage:
EntryPoint Vertex 4 EntryPoint Vertex 4
Name 4 "main" Name 4 "main"
Name 9 "i" Name 9 "i"
Name 15 "A" Name 25 "A"
Name 22 "B" Name 31 "B"
Name 25 "C" Name 34 "C"
Name 31 "D" Name 40 "D"
Name 34 "E" Name 43 "E"
Name 36 "F" Name 45 "F"
Name 43 "G" Name 47 "G"
Name 46 "gl_VertexID" Name 50 "gl_VertexID"
Name 47 "gl_InstanceID" Name 51 "gl_InstanceID"
Decorate 9(i) PrecisionHigh Decorate 9(i) PrecisionHigh
Decorate 15(A) PrecisionHigh Decorate 25(A) PrecisionHigh
Decorate 22(B) PrecisionHigh Decorate 31(B) PrecisionHigh
Decorate 25(C) PrecisionHigh Decorate 34(C) PrecisionHigh
Decorate 31(D) PrecisionHigh Decorate 40(D) PrecisionHigh
Decorate 34(E) PrecisionHigh Decorate 43(E) PrecisionHigh
Decorate 36(F) PrecisionHigh Decorate 45(F) PrecisionHigh
Decorate 43(G) PrecisionHigh Decorate 47(G) PrecisionHigh
Decorate 46(gl_VertexID) PrecisionHigh Decorate 50(gl_VertexID) PrecisionHigh
Decorate 46(gl_VertexID) BuiltIn VertexId Decorate 50(gl_VertexID) BuiltIn VertexId
Decorate 46(gl_VertexID) NoStaticUse Decorate 50(gl_VertexID) NoStaticUse
Decorate 47(gl_InstanceID) PrecisionHigh Decorate 51(gl_InstanceID) PrecisionHigh
Decorate 47(gl_InstanceID) BuiltIn InstanceId Decorate 51(gl_InstanceID) BuiltIn InstanceId
Decorate 47(gl_InstanceID) NoStaticUse Decorate 51(gl_InstanceID) NoStaticUse
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
7: TypeInt 32 1 7: TypeInt 32 1
8: TypePointer Function 7(int) 8: TypePointer Function 7(int)
10: 7(int) Constant 0 10: 7(int) Constant 0
17: 7(int) Constant 2 14: TypeBool
18: TypeBool 15: 14(bool) ConstantTrue
23: 7(int) Constant 1 20: 7(int) Constant 1
27: 7(int) Constant 5 22: 7(int) Constant 19
32: 7(int) Constant 3 27: 7(int) Constant 2
35: 7(int) Constant 42 32: 14(bool) ConstantFalse
37: 7(int) Constant 99 36: 7(int) Constant 5
40: 7(int) Constant 19 41: 7(int) Constant 3
44: 7(int) Constant 12 44: 7(int) Constant 42
45: TypePointer Input 7(int) 46: 7(int) Constant 99
46(gl_VertexID): 45(ptr) Variable Input 48: 7(int) Constant 12
47(gl_InstanceID): 45(ptr) Variable Input 49: TypePointer Input 7(int)
50(gl_VertexID): 49(ptr) Variable Input
51(gl_InstanceID): 49(ptr) Variable Input
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
9(i): 8(ptr) Variable Function 9(i): 8(ptr) Variable Function
15(A): 8(ptr) Variable Function 25(A): 8(ptr) Variable Function
22(B): 8(ptr) Variable Function 31(B): 8(ptr) Variable Function
25(C): 8(ptr) Variable Function 34(C): 8(ptr) Variable Function
31(D): 8(ptr) Variable Function 40(D): 8(ptr) Variable Function
34(E): 8(ptr) Variable Function 43(E): 8(ptr) Variable Function
36(F): 8(ptr) Variable Function 45(F): 8(ptr) Variable Function
43(G): 8(ptr) Variable Function 47(G): 8(ptr) Variable Function
Store 9(i) 10 Store 9(i) 10
Branch 11 Branch 11
11: Label 11: Label
13: 14(bool) Phi 15 5 32 29 32 39
LoopMerge 12 None LoopMerge 12 None
Branch 13 Branch 16
13: Label 16: Label
Store 15(A) 10 SelectionMerge 17 None
16: 7(int) Load 9(i) BranchConditional 13 17 18
19: 18(bool) IEqual 16 17 18: Label
SelectionMerge 21 None 19: 7(int) Load 9(i)
BranchConditional 19 20 21 21: 7(int) IAdd 19 20
20: Label Store 9(i) 21
Store 22(B) 23 23: 14(bool) SLessThan 21 22
Branch 14 SelectionMerge 24 None
BranchConditional 23 24 12
24: Label 24: Label
Store 25(C) 17 Branch 17
Branch 21 17: Label
21: Label Store 25(A) 10
26: 7(int) Load 9(i) 26: 7(int) Load 9(i)
28: 18(bool) IEqual 26 27 28: 14(bool) IEqual 26 27
SelectionMerge 30 None SelectionMerge 30 None
BranchConditional 28 29 30 BranchConditional 28 29 30
29: Label 29: Label
Store 31(D) 32 Store 31(B) 20
Branch 12 Branch 11
33: Label 33: Label
Store 34(E) 35 Store 34(C) 27
Branch 30 Branch 30
30: Label 30: Label
Store 36(F) 37 35: 7(int) Load 9(i)
Branch 14 37: 14(bool) IEqual 35 36
14: Label SelectionMerge 39 None
38: 7(int) Load 9(i) BranchConditional 37 38 39
39: 7(int) IAdd 38 23 38: Label
Store 9(i) 39 Store 40(D) 41
41: 18(bool) SLessThan 39 40 Branch 12
BranchConditional 41 42 12 42: Label
42: Label Store 43(E) 44
Branch 39
39: Label
Store 45(F) 46
Branch 11 Branch 11
12: Label 12: Label
Store 43(G) 44 Store 47(G) 48
Branch 6 Branch 6
6: Label 6: Label
Return Return

View File

@ -5,7 +5,7 @@ Linked fragment stage:
// Module Version 99 // Module Version 99
// Generated by (magic number): 51a00bb // Generated by (magic number): 51a00bb
// Id's are bound by 34 // Id's are bound by 38
Source GLSL 110 Source GLSL 110
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
@ -14,11 +14,11 @@ Linked fragment stage:
Name 4 "main" Name 4 "main"
Name 10 "color" Name 10 "color"
Name 12 "BaseColor" Name 12 "BaseColor"
Name 19 "bigColor" Name 25 "d"
Name 26 "d" Name 30 "bigColor"
Name 32 "gl_FragColor" Name 36 "gl_FragColor"
Decorate 12(BaseColor) Smooth Decorate 12(BaseColor) Smooth
Decorate 32(gl_FragColor) BuiltIn FragColor Decorate 36(gl_FragColor) BuiltIn FragColor
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
7: TypeFloat 32 7: TypeFloat 32
@ -26,13 +26,15 @@ Linked fragment stage:
9: TypePointer Function 8(fvec4) 9: TypePointer Function 8(fvec4)
11: TypePointer Input 8(fvec4) 11: TypePointer Input 8(fvec4)
12(BaseColor): 11(ptr) Variable Input 12(BaseColor): 11(ptr) Variable Input
18: TypePointer UniformConstant 8(fvec4) 17: TypeBool
19(bigColor): 18(ptr) Variable UniformConstant 18: 17(bool) ConstantTrue
25: TypePointer UniformConstant 7(float) 24: TypePointer UniformConstant 7(float)
26(d): 25(ptr) Variable UniformConstant 25(d): 24(ptr) Variable UniformConstant
28: TypeBool 29: TypePointer UniformConstant 8(fvec4)
31: TypePointer Output 8(fvec4) 30(bigColor): 29(ptr) Variable UniformConstant
32(gl_FragColor): 31(ptr) Variable Output 34: 17(bool) ConstantFalse
35: TypePointer Output 8(fvec4)
36(gl_FragColor): 35(ptr) Variable Output
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
10(color): 9(ptr) Variable Function 10(color): 9(ptr) Variable Function
@ -40,25 +42,30 @@ Linked fragment stage:
Store 10(color) 13 Store 10(color) 13
Branch 14 Branch 14
14: Label 14: Label
16: 17(bool) Phi 18 5 34 20
LoopMerge 15 None LoopMerge 15 None
Branch 16 Branch 19
16: Label 19: Label
20: 8(fvec4) Load 19(bigColor) SelectionMerge 20 None
21: 8(fvec4) Load 10(color) BranchConditional 16 20 21
22: 8(fvec4) FAdd 21 20 21: Label
Store 10(color) 22 22: 8(fvec4) Load 10(color)
Branch 17 23: 7(float) CompositeExtract 22 0
17: Label 26: 7(float) Load 25(d)
23: 8(fvec4) Load 10(color) 27: 17(bool) FOrdLessThan 23 26
24: 7(float) CompositeExtract 23 0 SelectionMerge 28 None
27: 7(float) Load 26(d) BranchConditional 27 28 15
29: 28(bool) FOrdLessThan 24 27 28: Label
BranchConditional 29 30 15 Branch 20
30: Label 20: Label
Branch 14 31: 8(fvec4) Load 30(bigColor)
32: 8(fvec4) Load 10(color)
33: 8(fvec4) FAdd 32 31
Store 10(color) 33
Branch 14
15: Label 15: Label
33: 8(fvec4) Load 10(color) 37: 8(fvec4) Load 10(color)
Store 32(gl_FragColor) 33 Store 36(gl_FragColor) 37
Branch 6 Branch 6
6: Label 6: Label
Return Return

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ Linked fragment stage:
// Module Version 99 // Module Version 99
// Generated by (magic number): 51a00bb // Generated by (magic number): 51a00bb
// Id's are bound by 192 // Id's are bound by 196
Source GLSL 130 Source GLSL 130
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
@ -16,98 +16,98 @@ Linked fragment stage:
Name 4 "main" Name 4 "main"
Name 10 "color" Name 10 "color"
Name 12 "BaseColor" Name 12 "BaseColor"
Name 19 "bigColor4" Name 25 "d4"
Name 26 "d4" Name 30 "bigColor4"
Name 79 "d13" Name 83 "d13"
Name 145 "gl_FragColor" Name 149 "gl_FragColor"
Name 147 "bigColor" Name 151 "bigColor"
Name 148 "bigColor1_1" Name 152 "bigColor1_1"
Name 149 "bigColor1_2" Name 153 "bigColor1_2"
Name 150 "bigColor1_3" Name 154 "bigColor1_3"
Name 151 "bigColor2" Name 155 "bigColor2"
Name 152 "bigColor3" Name 156 "bigColor3"
Name 153 "bigColor5" Name 157 "bigColor5"
Name 154 "bigColor6" Name 158 "bigColor6"
Name 155 "bigColor7" Name 159 "bigColor7"
Name 156 "bigColor8" Name 160 "bigColor8"
Name 157 "d" Name 161 "d"
Name 158 "d2" Name 162 "d2"
Name 159 "d3" Name 163 "d3"
Name 160 "d5" Name 164 "d5"
Name 161 "d6" Name 165 "d6"
Name 162 "d7" Name 166 "d7"
Name 163 "d8" Name 167 "d8"
Name 164 "d9" Name 168 "d9"
Name 165 "d10" Name 169 "d10"
Name 166 "d11" Name 170 "d11"
Name 167 "d12" Name 171 "d12"
Name 168 "d14" Name 172 "d14"
Name 169 "d15" Name 173 "d15"
Name 170 "d16" Name 174 "d16"
Name 171 "d17" Name 175 "d17"
Name 172 "d18" Name 176 "d18"
Name 173 "d19" Name 177 "d19"
Name 174 "d20" Name 178 "d20"
Name 175 "d21" Name 179 "d21"
Name 176 "d22" Name 180 "d22"
Name 177 "d23" Name 181 "d23"
Name 178 "d24" Name 182 "d24"
Name 179 "d25" Name 183 "d25"
Name 180 "d26" Name 184 "d26"
Name 181 "d27" Name 185 "d27"
Name 182 "d28" Name 186 "d28"
Name 183 "d29" Name 187 "d29"
Name 184 "d30" Name 188 "d30"
Name 185 "d31" Name 189 "d31"
Name 186 "d32" Name 190 "d32"
Name 187 "d33" Name 191 "d33"
Name 188 "d34" Name 192 "d34"
Name 191 "Count" Name 195 "Count"
Decorate 12(BaseColor) Smooth Decorate 12(BaseColor) Smooth
Decorate 145(gl_FragColor) BuiltIn FragColor Decorate 149(gl_FragColor) BuiltIn FragColor
Decorate 147(bigColor) NoStaticUse Decorate 151(bigColor) NoStaticUse
Decorate 148(bigColor1_1) NoStaticUse Decorate 152(bigColor1_1) NoStaticUse
Decorate 149(bigColor1_2) NoStaticUse Decorate 153(bigColor1_2) NoStaticUse
Decorate 150(bigColor1_3) NoStaticUse Decorate 154(bigColor1_3) NoStaticUse
Decorate 151(bigColor2) NoStaticUse Decorate 155(bigColor2) NoStaticUse
Decorate 152(bigColor3) NoStaticUse Decorate 156(bigColor3) NoStaticUse
Decorate 153(bigColor5) NoStaticUse Decorate 157(bigColor5) NoStaticUse
Decorate 154(bigColor6) NoStaticUse Decorate 158(bigColor6) NoStaticUse
Decorate 155(bigColor7) NoStaticUse Decorate 159(bigColor7) NoStaticUse
Decorate 156(bigColor8) NoStaticUse Decorate 160(bigColor8) NoStaticUse
Decorate 157(d) NoStaticUse Decorate 161(d) NoStaticUse
Decorate 158(d2) NoStaticUse Decorate 162(d2) NoStaticUse
Decorate 159(d3) NoStaticUse Decorate 163(d3) NoStaticUse
Decorate 160(d5) NoStaticUse Decorate 164(d5) NoStaticUse
Decorate 161(d6) NoStaticUse Decorate 165(d6) NoStaticUse
Decorate 162(d7) NoStaticUse Decorate 166(d7) NoStaticUse
Decorate 163(d8) NoStaticUse Decorate 167(d8) NoStaticUse
Decorate 164(d9) NoStaticUse Decorate 168(d9) NoStaticUse
Decorate 165(d10) NoStaticUse Decorate 169(d10) NoStaticUse
Decorate 166(d11) NoStaticUse Decorate 170(d11) NoStaticUse
Decorate 167(d12) NoStaticUse Decorate 171(d12) NoStaticUse
Decorate 168(d14) NoStaticUse Decorate 172(d14) NoStaticUse
Decorate 169(d15) NoStaticUse Decorate 173(d15) NoStaticUse
Decorate 170(d16) NoStaticUse Decorate 174(d16) NoStaticUse
Decorate 171(d17) NoStaticUse Decorate 175(d17) NoStaticUse
Decorate 172(d18) NoStaticUse Decorate 176(d18) NoStaticUse
Decorate 173(d19) NoStaticUse Decorate 177(d19) NoStaticUse
Decorate 174(d20) NoStaticUse Decorate 178(d20) NoStaticUse
Decorate 175(d21) NoStaticUse Decorate 179(d21) NoStaticUse
Decorate 176(d22) NoStaticUse Decorate 180(d22) NoStaticUse
Decorate 177(d23) NoStaticUse Decorate 181(d23) NoStaticUse
Decorate 178(d24) NoStaticUse Decorate 182(d24) NoStaticUse
Decorate 179(d25) NoStaticUse Decorate 183(d25) NoStaticUse
Decorate 180(d26) NoStaticUse Decorate 184(d26) NoStaticUse
Decorate 181(d27) NoStaticUse Decorate 185(d27) NoStaticUse
Decorate 182(d28) NoStaticUse Decorate 186(d28) NoStaticUse
Decorate 183(d29) NoStaticUse Decorate 187(d29) NoStaticUse
Decorate 184(d30) NoStaticUse Decorate 188(d30) NoStaticUse
Decorate 185(d31) NoStaticUse Decorate 189(d31) NoStaticUse
Decorate 186(d32) NoStaticUse Decorate 190(d32) NoStaticUse
Decorate 187(d33) NoStaticUse Decorate 191(d33) NoStaticUse
Decorate 188(d34) NoStaticUse Decorate 192(d34) NoStaticUse
Decorate 191(Count) NoStaticUse Decorate 195(Count) NoStaticUse
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
7: TypeFloat 32 7: TypeFloat 32
@ -115,61 +115,63 @@ Linked fragment stage:
9: TypePointer Function 8(fvec4) 9: TypePointer Function 8(fvec4)
11: TypePointer Input 8(fvec4) 11: TypePointer Input 8(fvec4)
12(BaseColor): 11(ptr) Variable Input 12(BaseColor): 11(ptr) Variable Input
18: TypePointer UniformConstant 8(fvec4) 17: TypeBool
19(bigColor4): 18(ptr) Variable UniformConstant 18: 17(bool) ConstantTrue
25: TypePointer UniformConstant 7(float) 24: TypePointer UniformConstant 7(float)
26(d4): 25(ptr) Variable UniformConstant 25(d4): 24(ptr) Variable UniformConstant
28: TypeBool 29: TypePointer UniformConstant 8(fvec4)
32: 7(float) Constant 1073741824 30(bigColor4): 29(ptr) Variable UniformConstant
46: 7(float) Constant 1065353216 40: 7(float) Constant 1073741824
79(d13): 25(ptr) Variable UniformConstant 54: 7(float) Constant 1065353216
144: TypePointer Output 8(fvec4) 58: 17(bool) ConstantFalse
145(gl_FragColor): 144(ptr) Variable Output 83(d13): 24(ptr) Variable UniformConstant
147(bigColor): 18(ptr) Variable UniformConstant 148: TypePointer Output 8(fvec4)
148(bigColor1_1): 18(ptr) Variable UniformConstant 149(gl_FragColor): 148(ptr) Variable Output
149(bigColor1_2): 18(ptr) Variable UniformConstant 151(bigColor): 29(ptr) Variable UniformConstant
150(bigColor1_3): 18(ptr) Variable UniformConstant 152(bigColor1_1): 29(ptr) Variable UniformConstant
151(bigColor2): 18(ptr) Variable UniformConstant 153(bigColor1_2): 29(ptr) Variable UniformConstant
152(bigColor3): 18(ptr) Variable UniformConstant 154(bigColor1_3): 29(ptr) Variable UniformConstant
153(bigColor5): 18(ptr) Variable UniformConstant 155(bigColor2): 29(ptr) Variable UniformConstant
154(bigColor6): 18(ptr) Variable UniformConstant 156(bigColor3): 29(ptr) Variable UniformConstant
155(bigColor7): 18(ptr) Variable UniformConstant 157(bigColor5): 29(ptr) Variable UniformConstant
156(bigColor8): 18(ptr) Variable UniformConstant 158(bigColor6): 29(ptr) Variable UniformConstant
157(d): 25(ptr) Variable UniformConstant 159(bigColor7): 29(ptr) Variable UniformConstant
158(d2): 25(ptr) Variable UniformConstant 160(bigColor8): 29(ptr) Variable UniformConstant
159(d3): 25(ptr) Variable UniformConstant 161(d): 24(ptr) Variable UniformConstant
160(d5): 25(ptr) Variable UniformConstant 162(d2): 24(ptr) Variable UniformConstant
161(d6): 25(ptr) Variable UniformConstant 163(d3): 24(ptr) Variable UniformConstant
162(d7): 25(ptr) Variable UniformConstant 164(d5): 24(ptr) Variable UniformConstant
163(d8): 25(ptr) Variable UniformConstant 165(d6): 24(ptr) Variable UniformConstant
164(d9): 25(ptr) Variable UniformConstant 166(d7): 24(ptr) Variable UniformConstant
165(d10): 25(ptr) Variable UniformConstant 167(d8): 24(ptr) Variable UniformConstant
166(d11): 25(ptr) Variable UniformConstant 168(d9): 24(ptr) Variable UniformConstant
167(d12): 25(ptr) Variable UniformConstant 169(d10): 24(ptr) Variable UniformConstant
168(d14): 25(ptr) Variable UniformConstant 170(d11): 24(ptr) Variable UniformConstant
169(d15): 25(ptr) Variable UniformConstant 171(d12): 24(ptr) Variable UniformConstant
170(d16): 25(ptr) Variable UniformConstant 172(d14): 24(ptr) Variable UniformConstant
171(d17): 25(ptr) Variable UniformConstant 173(d15): 24(ptr) Variable UniformConstant
172(d18): 25(ptr) Variable UniformConstant 174(d16): 24(ptr) Variable UniformConstant
173(d19): 25(ptr) Variable UniformConstant 175(d17): 24(ptr) Variable UniformConstant
174(d20): 25(ptr) Variable UniformConstant 176(d18): 24(ptr) Variable UniformConstant
175(d21): 25(ptr) Variable UniformConstant 177(d19): 24(ptr) Variable UniformConstant
176(d22): 25(ptr) Variable UniformConstant 178(d20): 24(ptr) Variable UniformConstant
177(d23): 25(ptr) Variable UniformConstant 179(d21): 24(ptr) Variable UniformConstant
178(d24): 25(ptr) Variable UniformConstant 180(d22): 24(ptr) Variable UniformConstant
179(d25): 25(ptr) Variable UniformConstant 181(d23): 24(ptr) Variable UniformConstant
180(d26): 25(ptr) Variable UniformConstant 182(d24): 24(ptr) Variable UniformConstant
181(d27): 25(ptr) Variable UniformConstant 183(d25): 24(ptr) Variable UniformConstant
182(d28): 25(ptr) Variable UniformConstant 184(d26): 24(ptr) Variable UniformConstant
183(d29): 25(ptr) Variable UniformConstant 185(d27): 24(ptr) Variable UniformConstant
184(d30): 25(ptr) Variable UniformConstant 186(d28): 24(ptr) Variable UniformConstant
185(d31): 25(ptr) Variable UniformConstant 187(d29): 24(ptr) Variable UniformConstant
186(d32): 25(ptr) Variable UniformConstant 188(d30): 24(ptr) Variable UniformConstant
187(d33): 25(ptr) Variable UniformConstant 189(d31): 24(ptr) Variable UniformConstant
188(d34): 25(ptr) Variable UniformConstant 190(d32): 24(ptr) Variable UniformConstant
189: TypeInt 32 1 191(d33): 24(ptr) Variable UniformConstant
190: TypePointer UniformConstant 189(int) 192(d34): 24(ptr) Variable UniformConstant
191(Count): 190(ptr) Variable UniformConstant 193: TypeInt 32 1
194: TypePointer UniformConstant 193(int)
195(Count): 194(ptr) Variable UniformConstant
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
10(color): 9(ptr) Variable Function 10(color): 9(ptr) Variable Function
@ -177,173 +179,178 @@ Linked fragment stage:
Store 10(color) 13 Store 10(color) 13
Branch 14 Branch 14
14: Label 14: Label
16: 17(bool) Phi 18 5 58 50 58 65
LoopMerge 15 None LoopMerge 15 None
Branch 16 Branch 19
16: Label 19: Label
20: 8(fvec4) Load 19(bigColor4) SelectionMerge 20 None
21: 8(fvec4) Load 10(color) BranchConditional 16 20 21
22: 8(fvec4) FAdd 21 20 21: Label
Store 10(color) 22 22: 8(fvec4) Load 10(color)
23: 8(fvec4) Load 10(color) 23: 7(float) CompositeExtract 22 2
24: 7(float) CompositeExtract 23 0 26: 7(float) Load 25(d4)
27: 7(float) Load 26(d4) 27: 17(bool) FOrdLessThan 23 26
29: 28(bool) FOrdLessThan 24 27 SelectionMerge 28 None
SelectionMerge 31 None BranchConditional 27 28 15
BranchConditional 29 30 31 28: Label
30: Label Branch 20
33: 8(fvec4) Load 10(color) 20: Label
34: 7(float) CompositeExtract 33 2 31: 8(fvec4) Load 30(bigColor4)
35: 7(float) FAdd 34 32 32: 8(fvec4) Load 10(color)
36: 8(fvec4) Load 10(color) 33: 8(fvec4) FAdd 32 31
37: 8(fvec4) CompositeInsert 35 36 2 Store 10(color) 33
Store 10(color) 37 34: 8(fvec4) Load 10(color)
38: 8(fvec4) Load 10(color) 35: 7(float) CompositeExtract 34 0
39: 7(float) CompositeExtract 38 2 36: 7(float) Load 25(d4)
40: 7(float) Load 26(d4) 37: 17(bool) FOrdLessThan 35 36
41: 28(bool) FOrdLessThan 39 40 SelectionMerge 39 None
SelectionMerge 43 None BranchConditional 37 38 39
BranchConditional 41 42 43 38: Label
42: Label 41: 8(fvec4) Load 10(color)
44: 8(fvec4) Load 10(color) 42: 7(float) CompositeExtract 41 2
45: 7(float) CompositeExtract 44 0 43: 7(float) FAdd 42 40
47: 7(float) FAdd 45 46 44: 8(fvec4) Load 10(color)
48: 8(fvec4) Load 10(color) 45: 8(fvec4) CompositeInsert 43 44 2
49: 8(fvec4) CompositeInsert 47 48 0 Store 10(color) 45
Store 10(color) 49 46: 8(fvec4) Load 10(color)
Branch 17 47: 7(float) CompositeExtract 46 2
43: Label 48: 7(float) Load 25(d4)
Branch 31 49: 17(bool) FOrdLessThan 47 48
31: Label SelectionMerge 51 None
51: 8(fvec4) Load 10(color) BranchConditional 49 50 51
52: 7(float) CompositeExtract 51 1 50: Label
53: 7(float) Load 26(d4) 52: 8(fvec4) Load 10(color)
54: 28(bool) FOrdLessThan 52 53 53: 7(float) CompositeExtract 52 0
SelectionMerge 56 None 55: 7(float) FAdd 53 54
BranchConditional 54 55 63 56: 8(fvec4) Load 10(color)
55: Label 57: 8(fvec4) CompositeInsert 55 56 0
57: 7(float) Load 26(d4) Store 10(color) 57
58: 8(fvec4) Load 10(color) Branch 14
59: 7(float) CompositeExtract 58 1 51: Label
60: 7(float) FAdd 59 57 Branch 39
61: 8(fvec4) Load 10(color) 39: Label
62: 8(fvec4) CompositeInsert 60 61 1 60: 8(fvec4) Load 10(color)
Store 10(color) 62 61: 7(float) CompositeExtract 60 1
Branch 56 62: 7(float) Load 25(d4)
63: Label 63: 17(bool) FOrdLessThan 61 62
64: 7(float) Load 26(d4) SelectionMerge 65 None
65: 8(fvec4) Load 10(color) BranchConditional 63 64 72
66: 7(float) CompositeExtract 65 0 64: Label
67: 7(float) FAdd 66 64 66: 7(float) Load 25(d4)
68: 8(fvec4) Load 10(color) 67: 8(fvec4) Load 10(color)
69: 8(fvec4) CompositeInsert 67 68 0 68: 7(float) CompositeExtract 67 1
Store 10(color) 69 69: 7(float) FAdd 68 66
Branch 56 70: 8(fvec4) Load 10(color)
56: Label 71: 8(fvec4) CompositeInsert 69 70 1
Branch 17 Store 10(color) 71
17: Label Branch 65
70: 8(fvec4) Load 10(color) 72: Label
71: 7(float) CompositeExtract 70 2 73: 7(float) Load 25(d4)
72: 7(float) Load 26(d4) 74: 8(fvec4) Load 10(color)
73: 28(bool) FOrdLessThan 71 72 75: 7(float) CompositeExtract 74 0
BranchConditional 73 74 15 76: 7(float) FAdd 75 73
74: Label 77: 8(fvec4) Load 10(color)
78: 8(fvec4) CompositeInsert 76 77 0
Store 10(color) 78
Branch 65
65: Label
Branch 14 Branch 14
15: Label 15: Label
Branch 75 Branch 79
75: Label 79: Label
77: 8(fvec4) Load 10(color) 81: 8(fvec4) Load 10(color)
78: 7(float) CompositeExtract 77 3 82: 7(float) CompositeExtract 81 3
80: 7(float) Load 79(d13) 84: 7(float) Load 83(d13)
81: 28(bool) FOrdLessThan 78 80 85: 17(bool) FOrdLessThan 82 84
LoopMerge 76 None LoopMerge 80 None
BranchConditional 81 82 76 BranchConditional 85 86 80
82: Label 86: Label
83: 8(fvec4) Load 10(color) 87: 8(fvec4) Load 10(color)
84: 7(float) CompositeExtract 83 2 88: 7(float) CompositeExtract 87 2
85: 7(float) Load 79(d13) 89: 7(float) Load 83(d13)
86: 28(bool) FOrdLessThan 84 85 90: 17(bool) FOrdLessThan 88 89
SelectionMerge 88 None SelectionMerge 92 None
BranchConditional 86 87 92 BranchConditional 90 91 96
87: Label 91: Label
89: 8(fvec4) Load 10(color)
90: 8(fvec4) CompositeConstruct 46 46 46 46
91: 8(fvec4) FAdd 89 90
Store 10(color) 91
Branch 88
92: Label
93: 8(fvec4) Load 10(color) 93: 8(fvec4) Load 10(color)
94: 8(fvec4) CompositeConstruct 46 46 46 46 94: 8(fvec4) CompositeConstruct 54 54 54 54
95: 8(fvec4) FSub 93 94 95: 8(fvec4) FAdd 93 94
Store 10(color) 95 Store 10(color) 95
Branch 88 Branch 92
88: Label 96: Label
96: 8(fvec4) Load 19(bigColor4) 97: 8(fvec4) Load 10(color)
97: 8(fvec4) Load 10(color) 98: 8(fvec4) CompositeConstruct 54 54 54 54
98: 8(fvec4) FAdd 97 96 99: 8(fvec4) FSub 97 98
Store 10(color) 98 Store 10(color) 99
99: 8(fvec4) Load 10(color) Branch 92
100: 7(float) CompositeExtract 99 0 92: Label
101: 7(float) Load 26(d4) 100: 8(fvec4) Load 30(bigColor4)
102: 28(bool) FOrdLessThan 100 101 101: 8(fvec4) Load 10(color)
SelectionMerge 104 None 102: 8(fvec4) FAdd 101 100
BranchConditional 102 103 104 Store 10(color) 102
103: Label 103: 8(fvec4) Load 10(color)
105: 8(fvec4) Load 10(color) 104: 7(float) CompositeExtract 103 0
106: 7(float) CompositeExtract 105 2 105: 7(float) Load 25(d4)
107: 7(float) FAdd 106 32 106: 17(bool) FOrdLessThan 104 105
108: 8(fvec4) Load 10(color) SelectionMerge 108 None
109: 8(fvec4) CompositeInsert 107 108 2 BranchConditional 106 107 108
Store 10(color) 109 107: Label
110: 8(fvec4) Load 10(color) 109: 8(fvec4) Load 10(color)
111: 7(float) CompositeExtract 110 2 110: 7(float) CompositeExtract 109 2
112: 7(float) Load 26(d4) 111: 7(float) FAdd 110 40
113: 28(bool) FOrdLessThan 111 112 112: 8(fvec4) Load 10(color)
SelectionMerge 115 None 113: 8(fvec4) CompositeInsert 111 112 2
BranchConditional 113 114 115 Store 10(color) 113
114: Label 114: 8(fvec4) Load 10(color)
116: 8(fvec4) Load 10(color) 115: 7(float) CompositeExtract 114 2
117: 7(float) CompositeExtract 116 0 116: 7(float) Load 25(d4)
118: 7(float) FAdd 117 46 117: 17(bool) FOrdLessThan 115 116
119: 8(fvec4) Load 10(color) SelectionMerge 119 None
120: 8(fvec4) CompositeInsert 118 119 0 BranchConditional 117 118 119
Store 10(color) 120 118: Label
Branch 75 120: 8(fvec4) Load 10(color)
115: Label 121: 7(float) CompositeExtract 120 0
Branch 104 122: 7(float) FAdd 121 54
104: Label 123: 8(fvec4) Load 10(color)
122: 8(fvec4) Load 10(color) 124: 8(fvec4) CompositeInsert 122 123 0
123: 7(float) CompositeExtract 122 1 Store 10(color) 124
124: 7(float) Load 26(d4) Branch 79
125: 28(bool) FOrdLessThan 123 124 119: Label
SelectionMerge 127 None Branch 108
BranchConditional 125 126 134 108: Label
126: Label 126: 8(fvec4) Load 10(color)
128: 7(float) Load 26(d4) 127: 7(float) CompositeExtract 126 1
129: 8(fvec4) Load 10(color) 128: 7(float) Load 25(d4)
130: 7(float) CompositeExtract 129 1 129: 17(bool) FOrdLessThan 127 128
131: 7(float) FAdd 130 128 SelectionMerge 131 None
132: 8(fvec4) Load 10(color) BranchConditional 129 130 138
133: 8(fvec4) CompositeInsert 131 132 1 130: Label
Store 10(color) 133 132: 7(float) Load 25(d4)
Branch 127 133: 8(fvec4) Load 10(color)
134: Label 134: 7(float) CompositeExtract 133 1
135: 7(float) Load 26(d4) 135: 7(float) FAdd 134 132
136: 8(fvec4) Load 10(color) 136: 8(fvec4) Load 10(color)
137: 7(float) CompositeExtract 136 0 137: 8(fvec4) CompositeInsert 135 136 1
138: 7(float) FAdd 137 135 Store 10(color) 137
139: 8(fvec4) Load 10(color) Branch 131
140: 8(fvec4) CompositeInsert 138 139 0 138: Label
Store 10(color) 140 139: 7(float) Load 25(d4)
Branch 127 140: 8(fvec4) Load 10(color)
127: Label 141: 7(float) CompositeExtract 140 0
Branch 75 142: 7(float) FAdd 141 139
76: Label 143: 8(fvec4) Load 10(color)
141: 8(fvec4) Load 10(color) 144: 8(fvec4) CompositeInsert 142 143 0
142: 8(fvec4) CompositeConstruct 46 46 46 46 Store 10(color) 144
143: 8(fvec4) FAdd 141 142 Branch 131
Store 10(color) 143 131: Label
146: 8(fvec4) Load 10(color) Branch 79
Store 145(gl_FragColor) 146 80: Label
145: 8(fvec4) Load 10(color)
146: 8(fvec4) CompositeConstruct 54 54 54 54
147: 8(fvec4) FAdd 145 146
Store 10(color) 147
150: 8(fvec4) Load 10(color)
Store 149(gl_FragColor) 150
Branch 6 Branch 6
6: Label 6: Label
Return Return