On Fri, May 10, 2024 at 1:27 AM Jose E. Marchesi <jose.marchesi@xxxxxxxxxx> wrote: > > > > On Thu, May 9, 2024 at 1:47 AM Jose E. Marchesi > > <jose.marchesi@xxxxxxxxxx> wrote: > >> +/* A `break' executed in the head of a `for' loop statement is bound > >> + to the current loop in clang, but it is bound to the enclosing loop > >> + in GCC. Note both compilers optimize the outer loop out with -O1 > >> + and higher. This macro shall be used to annotate any loop that > >> + uses cond_break within its header. */ > >> +#ifdef __clang__ > >> +#define __compat_break > >> +#else > >> +#define __compat_break for (int __control = 1; __control; --__control) > >> +#endif > > .. > >> + __compat_break > >> for (i = zero; i < cnt; cond_break, i++) { > >> struct elem __arena *n = bpf_alloc(sizeof(*n)); > > > > This is too ugly. It ruins the readability of the code. > > Let's introduce can_loop macro similar to cond_break > > that returns 0 or 1 instead of break/continue and use it as: > > > > for (i = zero; i < cnt && can_loop; i++) { > > > > pw-bot: cr > > I went with the ugliness because I was trying to avoid rewriting the > loops in the tests, assuming the tests were actually testing using > cond_break in these particular locations would result in a particular > number of iterations. > > The loops > > for (i = zero; i < cnt; cond_break, i++) BODY > > and > > for (i = zero; i < cnt && can_loop; i++) BODY > > are not equivalent if can_loop implements the same logic than > cond_break. It's off by one and it's fine. The loops don't and shouldn't expect the precise number allowed by may_goto. btw there are tests that use cond_break inside {}. They don't need to change. > > The may_goto instructions are somehow patched at run-time, and in a > predictable way since the tests are checking for explicit iteration > counts, right? They're patched by the verifier, but they're unpredictable. Right now it's a simpler counter, but sooner or later it will be time based.