[PATCH] D147116: [RFC] Introduce convergence control intrinsics

Eli Friedman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 15 15:48:08 PDT 2023


efriedma added a comment.

I'm wondering if there's a better way to represent loops.  At the core, the key notion for loop convergence is that all threads converge for every iteration.  So in general, a while loop is something like the following:

  start:
  @llvm.experimental.convergence.loop()
  if (!cond) goto end
  body;
  goto start;
  end:

For most cases, making this work doesn't require llvm.experimental.convergence.loop to return a token; the mere existence of a convergent call that executes on every thread every iteration forces the necessary structure on the code.  The problem is that after a "break" or "return" inside, the loop doesn't execute the llvm.experimental.convergence.loop call; to solve this, you make llvm.experimental.convergence.loop return a token, and impose a bunch of rules on the placement of the intrinsic and the usage of the token, so the control flow can be reconstructed.

But the fact that we don't execute the llvm.experimental.convergence.loop after a "break" isn't fundamental to the definition of "break", it's just an artifact of the way you're choosing to lower "break". You could instead define a hidden condition:

  bool didbreak = false;
  start:
  if (!cond) goto end
  body;
  @llvm.experimental.convergence.loop()
  if (didbreak) goto end
  goto start;
  end:

And then define "break" to be equivalent to "didbreak = true; continue;".  "return" requires generating a bit more code after the loop, but works similarly.

clang already has the infrastructure necessary to make this work; it's exactly the same kind of control flow you need for C++ destructors with "break"/"return".

The advantage of this formulation is that it makes the invariants for llvm.experimental.convergence.loop a lot simpler.  Actually, you don't need any special rules at all: the fact that the intrinsic is convergent dictates the result you want.  The disadvantage is that the scalar control flow is a bit more complicated.

(I'm really not an expert on convergence, so I might be missing something.  But I didn't see any other discussion along these lines.)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147116/new/

https://reviews.llvm.org/D147116



More information about the llvm-commits mailing list