Nadav Rotem <nrotem at apple.com> writes:> > For DIV/MOD you can blend the inputs BEFORE the operation. You > can > place ones or zeros depending on the operation. > > Quick follow-up on this. What about using "undef" as the input for > false items: > > tv1 = select mask, v1, undef > tv2 = select mask, v2, undef > tv3 = div tv1, tv2 > v3 = select mask, tv3, undef > > I'm always confused about the semantics of undef. Is the above > safe > code? It would simplify things a bit not to have to track which > input > values are safe based on the context of an operation. > > -David > > This is not a correct use of undef. I think that > InstCombine/DagCombine will optimize tv1 into 'undef'.But is that really a legal transformation? Clearly not all elements are known to be undef. But thanks for the feedback! We'll avoid this route for now. -David
On May 2, 2013, at 10:31 AM, dag at cray.com wrote:> But is that really a legal transformation? Clearly not all elements are > known to be undef.Hi David, This blog post explains the motivation for modeling undefined behavior: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html The idea is that you want to optimize your code based on the premise that undefined behavior in C allows you to do anything you like (to the undefined value). Thanks, Nadav -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130502/95baa73f/attachment.html>
On Thu, May 2, 2013 at 10:31 AM, <dag at cray.com> wrote:> Nadav Rotem <nrotem at apple.com> writes: > > > > > For DIV/MOD you can blend the inputs BEFORE the operation. You > > can > > place ones or zeros depending on the operation. > > > > Quick follow-up on this. What about using "undef" as the input for > > false items: > > > > tv1 = select mask, v1, undef > > tv2 = select mask, v2, undef > > tv3 = div tv1, tv2 > > v3 = select mask, tv3, undef > > > > I'm always confused about the semantics of undef. Is the above > > safe > > code? It would simplify things a bit not to have to track which > > input > > values are safe based on the context of an operation. >The selects with undef do indeed do what you intend here. They return vectors where the elements corresponding to true bits in the mask have defined values, and the other elements have undef values. Undef can indeed exist on a per-element basis, and LLVM is quite careful to implement this [0]. The real problem with this approach is that there's nothing guarding those undef elements from the div. If the undef elements happen to be 0, you'll divide by zero, which is undefined behavior. For a divide, it's either necessary to define the behavior of divide-by-zero (not what LLVM does today), or mask the divide itself.> > > -David > > > > This is not a correct use of undef. I think that > > InstCombine/DagCombine will optimize tv1 into 'undef'. >It is not valid to optimize tv1 to undef here. tv3 is the problem. Dan [0] undef can also exist on a per-bit basis: and(1, undef) is a value where the least significant bit is undef and the remaining bits are zero. Amusingly, undef can also exist on a non-bitwise basis: add(mul(urem(undef, 3), 17), 5) is a value which fluctuates among just the values 5, 22, and 39. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130502/99128dea/attachment.html>
Nadav Rotem <nrotem at apple.com> writes:> The idea is that you want to optimize your code based on the premise > that undefined behavior in C allows you to do anything you like (to > the undefined value).To the undefined value, sure, but how does that get extrapolated to treating the entire vector as undef? -David
Dan Gohman <dan433584 at gmail.com> writes:> The selects with undef do indeed do what you intend here. They return > vectors where the elements corresponding to true bits in the mask have > defined values, and the other elements have undef values. Undef can > indeed exist on a per-element basis, and LLVM is quite careful to > implement this [0].Ok, that's what I would expect.> The real problem with this approach is that there's nothing guarding > those undef elements from the div. If the undef elements happen to be > 0, you'll divide by zero, which is undefined behavior. For a divide, > it's either necessary to define the behavior of divide-by-zero (not > what LLVM does today), or mask the divide itself.The intent is to match the select/select/div/select as one masked divide instruction. I totally understand what you're saying and I know there is no guarantee that we will even see that construct way down in isel. But it seems to be the best we've got right now. Using safe values for false items is...er...safer. :) We'll probably do that and hope we can avoid the overhead at isel time. -David