[PATCH] D68994: [RFC] Redefine `convergent` in terms of dynamic instances

Nicolai Hähnle via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 29 03:46:52 PDT 2019


nhaehnle marked 2 inline comments as done.
nhaehnle added a comment.

In D68994#1724647 <https://reviews.llvm.org/D68994#1724647>, @kariddi wrote:

> What is the expectiation of lowering of a loop like the one you mentioned above?
>
> int divergent_key = ...;
>  int v = ...;
>  int sum;
>
>   for (;;;) {
>     tok = @llvm.convergence.anchor()
>     int uniform_key = readfirstlane(divergent_key);
>     if (uniform_key == divergent_key) {
>       sum = subgroup_reduce_add(v);
>       @llvm.convergence.point(tok)
>       break;
>     }
>   }
>
>
> In particular the expectation of lowering in LLVM-IR is typically that the block with the "break" is an exit block and as such is typically moved outside of the loop (when the threads are reconverted). Is the expectation to have LLVM.CONVERGENCE.POINT to be lowered to the backends with a pseudo instruction similar to DBG_VALUE (and then be ignored by regalloc and such) up to the point that final control-flow block ordering is defined so that the execution of the "unconverged" part of the exit block is lowered so that is executed inside the loop instead of outside?


Something along those lines, yes. The details would obviously depend on how the backend handles divergence and reconvergence. For example, in AMDGPU we fairly early on convert into a form where divergent values are computed using vector instructions, i.e. mostly explicitly SIMD instructions that use an EXEC physical register. So in our case, the intrinsic would affect this conversion of the code into SIMD form.



================
Comment at: llvm/docs/DynamicInstances.rst:61
+
+1. Every instruction in an LLVM IR function has zero or more dynamic instances.
+
----------------
kariddi wrote:
> While I like the idea of formalizing the whole "Dynamic Instances" concept I wonder if it could be explained in a more intuitive way as well in order to make the understanding of the formal definitions easier by approaching  them with an intuition already of what they are. 
I don't think we can get away without a formal description, but I'm not against having some more illustrative examples. Do you have anything in mind?


================
Comment at: llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1474
+      // with which the convergent operation communicates.
+      if (C->isConvergent())
+        return false;
----------------
kariddi wrote:
> Is this the only change in SimplifyCFG we would have to do?
> 
> What about FoldBranchToCommonDest() ? It seems to be hoisting instructions into the predecessors , but it just checks for the Speculable attribute (through isSafeToSpeculativelyExecute()) and seem to ignore the Convergent attribute.
> 
> In general how much the new behavior has been vetted around LLVM passes with respect respecting hoisting or changes in thread execution mask?
I've fixed the places that I was aware of based on bugs we've encountered over the years. I wouldn't be surprised if there were more places like you say...


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D68994





More information about the llvm-commits mailing list