summaryrefslogtreecommitdiff
path: root/docs/LangRef.html
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-09-07 22:52:39 +0000
committerChris Lattner <sabre@nondot.org>2009-09-07 22:52:39 +0000
commit48a109c36cfc70f14be60a18469db3bb4882370c (patch)
tree1d726da59d5b1f0abb54285df21fe743e9881c69 /docs/LangRef.html
parentef17e24aee69486b4d68b128f2a313fdddd6e475 (diff)
downloadllvm-48a109c36cfc70f14be60a18469db3bb4882370c.tar.gz
llvm-48a109c36cfc70f14be60a18469db3bb4882370c.tar.bz2
llvm-48a109c36cfc70f14be60a18469db3bb4882370c.tar.xz
describe undef semantics in some more detail.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81167 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'docs/LangRef.html')
-rw-r--r--docs/LangRef.html106
1 files changed, 101 insertions, 5 deletions
diff --git a/docs/LangRef.html b/docs/LangRef.html
index 586aefc874..4308d31273 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -2016,13 +2016,109 @@ Classifications</a> </div>
<div class="doc_subsection"><a name="undefvalues">Undefined Values</a></div>
<div class="doc_text">
-<p>The string '<tt>undef</tt>' is recognized as a type-less constant that has no
- specific value. Undefined values may be of any type and be used anywhere a
- constant is permitted.</p>
+<p>The string '<tt>undef</tt>' can be used anywhere a constant is expected, and
+ indicates that the user of the value may recieve an unspecified bit-pattern.
+ Undefined values may be of any type (other than label or void) and be used
+ anywhere a constant is permitted.</p>
-<p>Undefined values indicate to the compiler that the program is well defined no
- matter what value is used, giving the compiler more freedom to optimize.</p>
+<p>Undefined values are useful, because it indicates to the compiler that the
+ program is well defined no matter what value is used. This gives the
+ compiler more freedom to optimize. Here are some examples of (potentially
+ surprising) transformations that are valid (in pseudo IR):</p>
+
+<div class="doc_code">
+<pre>
+ %A = add %X, undef
+ %B = sub %X, undef
+ %C = xor %X, undef
+Safe:
+ %A = undef
+ %B = undef
+ %C = undef
+</pre>
+</div>
+
+<p>This is safe because all of the output bits are affected by the undef bits.
+Any output bit can have a zero or one depending on the input bits.</p>
+
+<div class="doc_code">
+<pre>
+ %A = or %X, undef
+ %B = and %X, undef
+Safe:
+ %A = -1
+ %B = 0
+Unsafe:
+ %A = undef
+ %B = undef
+</pre>
+</div>
+
+<p>These logical operations have bits that are not always affected by the input.
+For example, if "%X" has a zero bit, then the output of the 'and' operation will
+always be a zero, no matter what the corresponding bit from the undef is. As
+such, it is unsafe to optimizer or assume that the result of the and is undef.
+However, it is safe to assume that all bits of the undef are 0, and optimize the
+and to 0. Likewise, it is safe to assume that all the bits of the undef operand
+to the or could be set, allowing the or to be folded to -1.</p>
+
+<div class="doc_code">
+<pre>
+ %A = select undef, %X, %Y
+ %B = select undef, 42, %Y
+ %C = select %X, %Y, undef
+Safe:
+ %A = %X (or %Y)
+ %B = 42 (or %Y)
+ %C = %Y
+Unsafe:
+ %A = undef
+ %B = undef
+ %C = undef
+</pre>
+</div>
+
+<p>This set of examples show that undefined select (and conditional branch)
+conditions can go "either way" but they have to come from one of the two
+operands. In the %A example, if %X and %Y were both known to have a clear low
+bit, then %A would have to have a cleared low bit. However, in the %C example,
+the optimizer is allowed to assume that the undef operand could be the same as
+%Y, allowing the whole select to be eliminated.</p>
+
+
+<div class="doc_code">
+<pre>
+ %A = xor undef, undef
+
+ %B = undef
+ %C = xor %B, %B
+
+ %D = undef
+ %E = icmp lt %D, 4
+ %F = icmp gte %D, 4
+
+Safe:
+ %A = undef
+ %B = undef
+ %C = undef
+ %D = undef
+ %E = undef
+ %F = undef
+</pre>
+</div>
+
+<p>This example points out that two undef operands are not necessarily the same.
+This can be surprising to people (and also matches C semantics) where they
+assume that "X^X" is always zero, even if X is undef. This isn't true for a
+number of reasons, but the short answer is that an undef "variable" can
+arbitrarily change its value over its "live range". This is true because the
+"variable" doesn't actually <em>have a live range</em>. Instead, the value is
+logically read from arbitrary registers that happen to be around when needed,
+so the value is not neccesarily consistent over time. In fact, %A and %C need
+to have the same semantics of the core LLVM "replace all uses with" concept
+would not hold.</p>
+
</div>
<!-- ======================================================================= -->