<div dir="ltr"><div><div>Original inventor of the poison concept here.<br><br></div>Poison is a flawed concept. I proved it was flawed back in 2011 [0]<br><br>[0] <a href="http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-December/046368.html">http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-December/046368.html</a><br><br></div><div>And since then, other holes have been found. I'm not aware of any serious proposals for its replacement that do not have similar problems.<br><br></div><div>Also note that poison is very different from undef. Undef, as far as I know, remains an entirely coherent concept.<br></div><div><br></div>Dan<br><div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Sep 9, 2014 at 6:50 AM, 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:1px solid rgb(204,204,204);padding-left:1ex">In the section about poison values, the LLVM language reference manual says:<br>
<br>
"Values other than phi nodes depend on their operands."<br>
<br>
This implies that a select instruction's output can be poisoned by its not-selected argument value. If select were poisoned only by its selected argument, we would expect this fact to be mentioned specifically, as it is for phi.<br>
<br>
Next I'll show how poisoning by the not-selected value can introduce a problem. Take this C program:<br>
<br>
int printf(const char *, ...);<br>
int foo(int x0) {<br>
int x3 = x0 >> 27;<br>
int x4 = x3 - 27;<br>
int x2 = x4 ? x4 : (1 >> x4);<br>
int x1 = x2 != 0;<br>
return x1;<br>
}<br>
int arg;<br>
int main (void) {<br>
int x1 = foo(arg);<br>
printf("%x\n", x1);<br>
return 0;<br>
}<br>
<br>
This program has no UB and it should print "1'.<br>
<br>
Clang at -O2 turns foo() into this:<br>
<br>
define i32 @foo(i32 %x0) #0 {<br>
entry:<br>
%shr = ashr i32 %x0, 27<br>
%sub = add nsw i32 %shr, -27<br>
%tobool = icmp ne i32 %sub, 0<br>
%shr1 = lshr i32 1, %sub<br>
%cond = select i1 %tobool, i32 %sub, i32 %shr1<br>
%cmp = icmp ne i32 %cond, 0<br>
%conv = zext i1 %cmp to i32<br>
ret i32 %conv<br>
}<br>
<br>
Although the translation is very straightforward, there's a problem: %shr1 is a poison value and although it is not selected, it propagates through the rest of the function and poisons the return value.<br>
<br>
Obviously things are not going well if the source program contains no UB and the emitted code returns a poison value. Either there has been a miscompilation or else the LLVM documentation should be changed to make it clear that the select instruction only has a value dependence on the value that is selected.<br>
<br>
The immediate problem here is that both Souper and Alive are happy for foo() to return 0 instead of 1. Souper actually does this optimization -- legally, of course, according to the reference manual.<br>
<br>
Anyway this issue seemed tricky enough to bring up here instead of just filing a PR.<br>
<br>
Thanks,<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>
</blockquote></div><br></div></div></div></div></div>