<div dir="ltr">This thread is already churning, so I apologize if by being late to the party I have missed important information.<div><br></div><div>The "apply_mask" approach is very familiar to me, in that I spent a lot of time thinking about how masking could be added pervasively to LLVM without disrupting the currently nice property that most of the standard arithmetic instructions are "overloaded" to work on all types.</div>
<div><br></div><div>The space of options that I saw available (and please don't judge these options just yet, I am well aware that some of them are abhorrent):</div><div><br></div><div>1 - Make masking explicit and change every potentially side-effecting operation to include an i1 mask in the scalar case and i1 vector mask in the vector case.</div>
<div>2 - Add specialized masked versions of these operations (distinct from the unmasked versions) either as intrinsics or new instructions</div><div>3 - Add an implicit mask that all vector operations occur "under" along with operations to set/get (or push/pop) this mask.</div>
<div>4 - Like 3 but add some notion of a "vector branch" - that is a conditional branch on a vector of i1 values instead of a single i1, which would implicitly do "the right thing" for masking.</div><div>
5 - Add a new type for "partial" vectors that combines a vector and same-sized mask. Operations overloaded for normal vectors would also work on partial vectors (and not operate on "missing" elements), and would produce partial results.</div>
<div><br></div><div>1 and 2 are the more-or-less straightforward approaches being considered, and involve either plumbing through new operations, or new semantics for old operations. There is nontrivial (I expect) but straightforward (again, I expect) work involved in either. The rest of the options try to avoid some or all of that work and/or provide niceties for end users at the expense of being "clever".</div>
<div><br></div><div>Options 3 and 4 are almost certainly outside of the realm of what LLVM should consider. One of the best things about SSA is how explicit it makes dependencies, so adding any kind of implicit mask that is carried behind people's backs is really scary.</div>
<div><br></div><div>Option 5 is (to my understanding) equivalent to this whole "apply_mask" approach being discussed, although the latter tries to avoid introducing a new type. Even though "apply_mask" doesn't explicitly introduce a new type, there are all kinds of special rules about when and where a value that has been "apply_mask"'d can be used. Adding a type to represent partiality allows these rules to be made explicit as part of type-checking the IR.</div>
<div><br></div><div>Such partial vectors are still fairly non-orthogonal, so it is unclear whether the end-user experience is worth whatever complexity it adds to the IR.</div><div><br></div><div>Anyway, that's my breakdown of the situation. I welcome any feedback from those with a better understanding of the consequences of any of these approaches...</div>
<div><br></div><div>- Tim</div><div><br></div></div>