Refine the design of cir.while
I'm hoping we could refine the design of
cir.whileoperations here and address the issues I mentioned above. But in case infeasible, I think I'm going to hard-code the pattern here and teach ClangIR to emitcir.invariant_groupelsewhere where appropriate. (Maybe emit it into the body of the while loop?)
Originally posted by @Lancern in https://github.com/llvm/clangir/pull/1261#discussion_r1949469919
Here is a more detailed explanation about this issue.
Consider the following C/C++ code:
while (int x = foo()) { /* body */ }
According to the standard^1, the code above is strictly equivalent to the following code:
label: {
int x = foo();
if (x) {
/* body */
goto label;
}
}
However, currently CIRGen emits the following CIR from the code (simplified for simplicity):
cir.scope {
%x.slot = cir.alloca !s32i
cir.while {
%0 = cir.call @foo()
cir.store %0, %x.slot
%1 = cir.load %x.slot
%2 = cir.cast int_to_bool %1
cir.condition(%2)
} do {
// body
}
}
The problem here is the cir.alloca operation not being emitted inside the cir.while operation, which may lead to wrong lifetime indication of the alloca-ed object. We may want to refine the design of the cir.while operation and include the alloca for its condition variable in its region.
In general, I have put my eyes on the IR design of CIR loops and wanted to find time moving it to something that would allow this to happen. You can see #1267 for example. I believe that there’s a big overlap here: if we harmonize the do-while and while loops similarly to how scf does, and also add support for region arguments we may easily allow the construct like you are describing above: defining the alloca in the condition region and passing its result into the body region without and not carrying it over again.
If not actually contributing this, as my free time lately has been on the scarce side, I’d be happy to actively participate in the design process and to lend initial review guidance :)
Thanks @orbiri
In general, I have put my eyes on the IR design of CIR loops and wanted to find time moving it to something that would allow this to happen. You can see https://github.com/llvm/clangir/issues/1267 for example.
@orbiri Thanks for the pointer and the idea looks promising to me! I'll try to realize it in cir.while.