<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Oct 18, 2016 at 5:42 PM, Nuno Lopes via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Okay; so the problem is that an instruction that is value-equivalent<br>
to a poison value is not itself necessarily poison?<br>
</blockquote>
<br>
Right.<br>
I think there were other examples, but I don't have them here handy. But<br>
at least this one is very problematic for GVN.<br>
</blockquote>
<br>
Another example is this:<br>
<br>
void f(int k) {<br>
 if (k != 0) {<br>
   for (< finite loop >) {<br>
     if (always_false_at_runtime) {<br>
       print(1 / k);<br>
     }<br>
   }<br>
 }<br>
}<br>
<br>
We'd like to hoist the `1 / k` computation to the preheader.  However, we can't do that today if `k` is undef, and we've defined branching on undef to be a non-deterministic choice.<br>
</blockquote>
<br>
This one isn’t clear to me: you can fold 1/k -> 1 when k is undef. And then it is a constant which makes no point to hoist?<br>
</blockquote>
<br></span>
Imagine that k is not a constant. Then you would like to hoist it to outside of the loop.<br>
It seems safe to hoist it since we know k != 0 by the enclosing 'if'.  And so we transform the function into:<br>
<br>
if (k != 0) {<br>
  int t = 1 / k;<span><br>
  for (< finite loop >) {<br>
     if (always_false_at_runtime) {<br></span>
        print(t);<br>
     }<br>
  }<br>
}<br>
<br>
Now you realize that k is undef and you get:<br></blockquote><div>Can IR (with/without your proposal) differentiate between C's "trap representations" and "unspecified values"?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
if (<non-deterministic branch>) {<br>
  int t = 1 / undef;<span><br>
  for (< finite loop >) {<br>
     if (always_false_at_runtime) {<br></span>
        print(t);<br>
     }<br>
  }<br>
}<br>
<br>
We can know chose to change the if condition to true and the undef in the division to zero (remember each use of undef can yield a different result).<br>
Now we have undefined behavior (UB) because we've introduced a division by zero (which would not happen in the original program).<br>
If branching on poison was UB instead then the original program was already executing UB so the transformation was fine.<br>
<br>
This example can be fixed by freezing k instead. That way we ensure that k is actually non-zero within the 'if' statement.<span class="m_-8496582442262309374HOEnZb"><font color="#888888"><br>
<br>
Nuno <br></font></span><div class="m_-8496582442262309374HOEnZb"><div class="m_-8496582442262309374h5">
______________________________<wbr>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
</div></div></blockquote></div><br></div></div>