<div dir="ltr"><div>I believe Dan struck at the heart of the issue and the consequences have just become apparent (at least to me).<br></div><div><br></div><div>Consider:</div><div><div>define i32 @f(i32 %a) {</div><div>  %cmp = icmp sgt i32 %a, 0</div><div>  %sub = sub nsw i32 2147483647, %a</div><div>  %sel = select i1 %cmp, i32 %sub, i32 0</div><div>  ret i32 %sel</div><div>}</div></div><div><br></div><div>If %a is -1, %sub will wrap and be poison. %cmp will be false.</div><div>Is %sel poison or not?  We have no definition for what select actually does.</div><div><br></div><div>If we assume select boils down to nothing but arithmetic, then %sel may be poisoned by *any* of its operands.</div><div><br></div><div>If we assume select boils down to control flow (branch + PHI), then we are violating the rules by which it operates in many places in LLVM.</div><div>Consider the following input:</div><div><div>%add = add nsw i32 %a, 1</div><div>%cmp1 = icmp eq i32 %a, 0</div><div>%cmp2 = icmp slt i32 %add, 0</div><div>%sel = select i1 %cmp1, i1 %cmp2, i1 false</div></div><div><br></div><div>We currently optimize this to:</div><div><div>%add = add nsw i32 %a, 1</div><div>%cmp1 = icmp eq i32 %a, 0</div><div>%cmp2 = icmp slt i32 %add, 0</div><div>%and = and i1 %cmp1, %cmp2</div></div><div><br></div><div>If %a is 2147483647: %add is poison, %cmp1 is false, %cmp2 is poison, %sel is false but %and is poison!</div><div><br></div><div>The above transform is not an oddity, InstCombine does this sort of thing *a lot*.</div><div><br></div><div>If select is arithmetic, many transforms are "correct" but we can form select far less often than we thought we could.</div><div>If select is control flow, many transforms are "wrong" but we might be able to form more selects.</div><div><br></div><div>What is select? How does it work? How should it work?</div>







<div class="gmail_extra"><br><div class="gmail_quote">On Thu, Sep 18, 2014 at 7:45 PM, John Regehr <span dir="ltr"><<a href="mailto:regehr@cs.utah.edu" target="_blank">regehr@cs.utah.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Today I ran into another aspect of the poison problem...<br>
<br>
Basically, SimplifyCFG wants to take<br>
<br>
  expr1 && expr2<br>
<br>
and flatten it into<br>
<br>
  x = expr1<br>
  y = expr2<br>
  x&y<br>
<br>
This isn't safe when expr2 might execute UB.  The consequence is that no LLVM shift instruction is safe to speculatively execute, nor is any nsw/nuw/exact variant, unless the operands can be proven to be in bounds.<br>
<br>
Real example here:<br>
<br>
  <a href="http://llvm.org/bugs/show_bug.cgi?id=20997" target="_blank">http://llvm.org/bugs/show_bug.<u></u>cgi?id=20997</a><div class=""><div class="h5"><br>
<br>
John<br>
______________________________<u></u>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/llvmdev</a><br>
</div></div></blockquote></div><br></div></div>