Also add a comment briefly explaining what ifcnv is.
It's unsafe to duplicate blocks that contain convergent instructions during ifcnv. See the patch for details.
Differential D17518
[ifcnv] Don't duplicate blocks that contain convergent instructions. jlebar on Feb 22 2016, 11:16 AM. Authored by
Details Also add a comment briefly explaining what ifcnv is. It's unsafe to duplicate blocks that contain convergent instructions during ifcnv. See the patch for details.
Diff Detail
Event TimelineComment Actions Friendly ping. Based on the discussion in D17430, this does seem confusing enough to be worth a comment. Comment Actions I'm not sure I understand the comment. This transform is basically turning ifs into predicated instructions, right? And we're basically saying that a predicated convergent operation (threadsync or what have you) is the same as having the operation in a conditional basic block? Comment Actions Not quite. The simple case of converting if (pred) __syncthreads(); ==> (predicated on pred) __syncthreads(); is trivially safe, like I think you're saying. But ifconv can also perform A simple example is BB0 / \ BB1 BB2 |\_ _/ | | | | TBB --> exit | FBB TBB forms ifconv's "simple" shape with its predecessors. Can we move TBB's I'd argued in D17430 that this was safe, but now I think it is not. If we
But clearly that's not necessarily true in this example. In terms of the LLVM spec, we say that you're not allowed to "add" a (BB1 && cond) || BB2 But after predication, we have two copies of the convergent operation: BB1 && cond BB2 I think my mistake earlier was concluding from this that we "removed" CFG BB1 && cond && !BB2 BB2 && !BB1 Now it's suddenly clear that we added a CFG dependency to each of these new Put another way, there's a set of control flows which result in us reaching an @resistor, I'm going to revert this back to what we originally had in D17430.
Comment Actions Thank you for the review, Hal. This is really pushing my ASCII art skills. lmk if this makes any more sense. |