I have not thought deeply into whether branching causes issues. What is the issue that you see?
Without structured_region, the MLIR could look something like this, and in this case it would require complex analysis to find the yielded loop variable -
%outer, %inner = omp.canonical_loop %i in [0, %tc) {
%t = llvm.icmp sgt i32 %0, 0
llvm.condbr %t, ^truebb(), ^falsebb()
^truebb:
%inner = omp.canonical_loop {...}
omp.yield %inner
^falsebb:
%inner1 = omp.canonical_loop {...}
omp.yield %inner1
}
We came up with omp.structured_region to avoid such cases and force a single basic block with one omp.yield. This would make sure we know at compile time which loop is yielded.
In the same scenario, with the structured region, the code would look like this -
%outer, %inner = omp.canonical_loop %i in [0, %tc) {
%inner2 = omp.structured_region {
%t = llvm.icmp sgt i32 %0, 0
llvm.condbr %t, ^truebb(), ^falsebb()
^truebb:
%inner = omp.canonical_loop {...}
omp.yield %inner
^falsebb:
%inner1 = omp.canonical_loop {...}
omp.yield %inner1
}
omp.yield %inner2
}
We now have a single omp.yield under the omp.canonical_loop but we have the same problem of statically figuring out at compile time, the yielded loop from the structured region.
Without structured_region, if we cannot have this problem, and the frontend makes sure we have a single omp.yield with a single possible canonical loop inside the region of canonical loop, even with branches in the region associated with the canonical loop, then we do not need a structured_region operation.
This is my understanding of the problem. Am I missing something?