<p dir="ltr">If we follow the RFC, the following program has UB if X is poison but is well defined if X is undef:</p>
<p dir="ltr">%loc = select i1 X, %global0, %global1<br>
store 42 to %loc</p>
<p dir="ltr">(Assuming both global0 and global1 can be legally stored to and are different locations.)</p>
<p dir="ltr">-- Sanjoy</p>
<p dir="ltr">Sent from a mobile device, please excuse typos.</p>
<div class="gmail_quote">On Jan 28, 2015 9:02 PM, "Philip Reames" <<a href="mailto:listmail@philipreames.com">listmail@philipreames.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000">
<div>On 01/28/2015 07:02 AM, Sean Silva
wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">Could you maybe provide an example where replacing
`%always_poison` with `undef` will change the meaning? At least
for me, the thing that I'm most unclear about is how poison
differs from undef.</div>
</blockquote>
I will second this request for much the same reason.<br>
<blockquote type="cite">
<div dir="ltr">
<div><br>
</div>
<div>-- Sean Silva</div>
</div>
<div class="gmail_extra"><br>
<div class="gmail_quote">On Wed, Jan 28, 2015 at 2:50 AM, David
Majnemer <span dir="ltr"><<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">Hello,
<div><br>
</div>
<div>What follows is my attempt to describe how poison
works. Let me know what you think.</div>
<div><br>
</div>
<div>-- </div>
<div>David</div>
<div><br>
</div>
<div><br>
</div>
<div>
<div># LLVM Poison Semantics</div>
<div><br>
</div>
<div>Poison is an LLVM concept which exists solely to
enable further optimization of LLVM IR. The exact
behavior of poison has been, to say the least,
confusing for users, researchers and engineers working
with LLVM.</div>
<div><br>
</div>
<div>This document hopes to clear up some of the
confusion of poison and hopefully explain *why* it has
its semantics.</div>
<div><br>
</div>
<div>## A Quick Introduction to Poison</div>
<div><br>
</div>
<div>Let's start with a concrete motivating example in
C:</div>
<div>```</div>
<div>int isSumGreater(int a, int b) {</div>
<div> return a + b > a;</div>
<div>}</div>
<div>```</div>
<div><br>
</div>
<div>The C specification permits us to optimize the
comparison in `isSumGreater` to `b > 0` because
signed overflow results in undefined behavior. A
reasonable translation of `isSumGreater` to LLVM IR
could be:</div>
<div><br>
</div>
<div>```</div>
<div>define i32 @isSumGreater(i32 %a, i32 %b) {</div>
<div>entry:</div>
<div> %add = add i32 %a, %b</div>
<div> %cmp = icmp sgt i32 %add, %a</div>
<div> %conv = zext i1 %cmp to i32</div>
<div> ret i32 %conv</div>
<div>}</div>
<div>```</div>
<div><br>
</div>
<div>However, LLVM cannot determine that `%cmp` should
not consider cases where `%add` resulted in signed
overflow. We need a way to communicate this
information to LLVM.</div>
<div><br>
</div>
<div>This is where the `nsw` and `nuw` flags come into
play. `nsw` is short for "no signed wrap", `nuw` is
short for "no unsigned wrap".</div>
<div><br>
</div>
<div>With these, we can come up with a new formulation
of `%add`: `add i32 nsw %a, %b`.</div>
<div>LLVM can take this into account when it is
optimizing the `%cmp` and replace it with: `icmp sgt
i32 %b, 0`.</div>
<div><br>
</div>
<div>## Differences Between LLVM and C/C++</div>
<div><br>
</div>
<div>There are some interesting differences between what
C++ and C specify and how LLVM behaves with respect to
performing an operationg which is not permitted to
overflow. </div>
<div><br>
</div>
<div>Perhaps chief among them is that evaluating an
expression in C++ or C which results performs an
overflow is undefined behavior. In LLVM, executing an
instruction which is marked `nsw` but which violates
signed overflow results in poison. Values which have
no relationship with poisoned values are not effected
by them.</div>
<div><br>
</div>
<div>Let us take the following C program into
consideration:</div>
<div>```</div>
<div>int calculateImportantResult(int a, int b) {</div>
<div> int result = 0;</div>
<div> if (a) {</div>
<div> result = a + b;</div>
<div> }</div>
<div> return result;</div>
<div>}</div>
<div>```</div>
<div><br>
</div>
<div>A straightforward lowering to LLVM IR could be:</div>
<div>```</div>
<div>define i32 @calculateImportantResult(i32 %a, i32
%b) {</div>
<div>entry:</div>
<div> %tobool = icmp ne i32 %a, 0</div>
<div> br i1 %tobool, label %if.then, label %if.end</div>
<div><br>
</div>
<div>if.then:</div>
<div> %add = add nsw i32 %a, %b</div>
<div> br label %if.end</div>
<div><br>
</div>
<div>if.end:</div>
<div> %result = phi i32 [ %add, %if.then ], [ 0, %entry
]</div>
<div> ret i32 %result</div>
<div>}</div>
<div>```</div>
<div><br>
</div>
<div>Moving `%add` to the `%entry` block would be
preferable and would allow further optimizations:</div>
<div>```</div>
<div>define i32 @calculateImportantResult(i32 %a, i32
%b) {</div>
<div>entry:</div>
<div> %tobool = icmp ne i32 %a, 0</div>
<div> %add = add nsw i32 %a, %b</div>
<div> %result = select i1 %tobool, i32 0, i32 %add</div>
<div> ret i32 %result</div>
<div>}</div>
<div>```</div>
<div><br>
</div>
<div>In the original code, the calculation of `%add` was
control dependent.</div>
<div>Now, `%add` might result in signed overflow in
violation of the `nsw` flag.</div>
<div>Despite this, the program should behave as it did
before because the poisoned value is masked-out by the
select. The next section will dive into this in
greater detail.</div>
<div><br>
</div>
<div># Computation Involving Poison Values</div>
<div>Poison in a computation results in poison if the
result cannot be constrained by its non-poison
operands.</div>
<div><br>
</div>
<div>Examples of this rule which will result in poison:</div>
<div>```</div>
<div> %add = add i32 %x, %always_poison</div>
<div> %sub = sub i32 %x, %always_poison</div>
<div> %xor = xor i32 %x, %always_poison</div>
<div> %mul = mul i32 %always_poison, 1</div>
<div>```</div>
<div><br>
</div>
<div>Examples of this rule which do not result in
poison:</div>
<div>```</div>
<div> %or = or i32 %always_poison, 2</div>
<div> %and = and i32 %always_poison, 2</div>
<div> %mul = mul i32 %always_poison, 0</div>
<div>```</div>
<div><br>
</div>
<div>In fact, it would be reasonable to optimize `%or`
to `2` and `%and` to `0`. In this respect, poison is
not different from `undef`.</div>
<div><br>
</div>
<div>The following example is only poison if `%cond` is
false:</div>
<div>```</div>
<div> %sel = select i1 %cond, i32 2, %always_poison</div>
<div>```</div>
<div><br>
</div>
<div>### Is it safe to have poison as a `call` argument?</div>
<div><br>
</div>
<div>A `call` instruction may or may not result in
poison depending on exactly how the callee uses the
supplied arguments, it is not necessarily the case
that `call i32 @someFunction(i32 %always_poison)`
results in poison.</div>
<div><br>
</div>
<div>LLVM cannot forbid poison from entering `call`
arguments without prohibiting an optimization pass
from outlining code.</div>
<div><br>
</div>
<div>### Is it safe to store poison to memory?</div>
<div><br>
</div>
<div>`store i32 %always_poison, i32* %mem` does not
result in undefined behavior. A subsequent load
instruction like `%load = load i32* %mem` will result
in `%load` being a poison value.</div>
<div><br>
</div>
<div>### Is it safe to load or store a poison memory
location?</div>
<div><br>
</div>
<div>No. Poison works just like `undef` in this
respect.</div>
<div><br>
</div>
<div>### Does comparing a poison value result in poison?</div>
<div><br>
</div>
<div>It depends. If the comparison couldn't solely be
determined by looking at the other operand, the result
is poison.</div>
<div><br>
</div>
<div>For example, `icmp i32 ule %always_poison,
4294967295` is `true`, not poison.</div>
<div>However, `icmp i32 ne %always_poison, 7` is poison.</div>
<div><br>
</div>
<div>### What if the condition operand in a `select` is
poison?</div>
<div><br>
</div>
<div>In the example `%sel = select i1 %always_poison, i1
true, false`, `%sel` is either `true` or `false`.
Because, `%sel` depends on `%always_poison` it too is
poison.</div>
</div>
</div>
<br>
_______________________________________________<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/mailman/listinfo/llvmdev</a><br>
<br>
</blockquote>
</div>
<br>
</div>
<br>
<fieldset></fieldset>
<br>
<pre>_______________________________________________
LLVM Developers mailing list
<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>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a>
</pre>
</blockquote>
<br>
</div>
<br>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">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/mailman/listinfo/llvmdev</a><br>
<br></blockquote></div>