I'm trying to understand the SPIR-V spec, understanding for loops for example. In the beginning of the 1.6 revision 2 spec, the following example (taking only part of it for consisveness)
for (int i = 0; i < 4; ++i)
color *= multiplier;
turns into:
%49 = OpLabel
OpLoopMerge %51 %52 None ; structured loop
OpBranch %53
%53 = OpLabel
%54 = OpLoad %16 %48
%56 = OpSLessThan %25 %54 %55 ; i < 4 ?
OpBranchConditional %56 %50 %51 ; body or break
%50 = OpLabel ; body
%58 = OpLoad %7 %57
%59 = OpLoad %7 %31
%60 = OpFMul %7 %59 %58
OpStore %31 %60
OpBranch %52
%52 = OpLabel ; continue target
%61 = OpLoad %16 %48
%62 = OpIAdd %16 %61 %21 ; ++i
OpStore %48 %62
OpBranch %49 ; loop back
%51 = OpLabel ; loop merge point
OpReturn
OpFunctionEnd
In the spec, it specifies a block starts with a label, and ends with a any branch termination instruction. This turns the above into the following:
;Block 1
%49 = OpLabel
OpLoopMerge %51 %52 None ; structured loop
OpBranch %53
;Block 2
%53 = OpLabel
%54 = OpLoad %16 %48
%56 = OpSLessThan %25 %54 %55 ; i < 4 ?
OpBranchConditional %56 %50 %51 ; body or break
;Block 3
%50 = OpLabel ; body
%58 = OpLoad %7 %57
%59 = OpLoad %7 %31
%60 = OpFMul %7 %59 %58
OpStore %31 %60
OpBranch %52
;Block 4
%52 = OpLabel ; continue target
%61 = OpLoad %16 %48
%62 = OpIAdd %16 %61 %21 ; ++i
OpStore %48 %62
OpBranch %49 ; loop back
;Block 5
%51 = OpLabel ; loop merge point
OpReturn
OpFunctionEnd
Then the spec states:
Header Block: A block containing a merge instruction.
Loop Header: A header block whose merge instruction is an OpLoopMerge
So the loop header here is block 1, where OpLoopMerge is located.
OpLoopMerge claims three parameters, two which matter here:
Merge Block is the label of the merge block for this structured loop.
Continue Target is the label of a block targeted for processing a loop "continue".
Merge block is
Merge Block: A block declared by the Merge Block operand of a merge instruction.
Which my understanding is when the "structured loop/selection" ends, in this case it's right at the end of the function, block 5. This then makes sense to me.
The Continue target is what isn't clear to me. The continue target here is block 4, according to the op loop merge instruction. Why is the continue target not block 3? or block 2? What makes block 4 the continue target here? Is it because it's the block where the final decision is made to exit or continue the loop? is that what is meant by "processing a loop "continue"?