diff --git a/docs/LangRef.html b/docs/LangRef.html index 586aefc874d..4308d312730 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -2016,13 +2016,109 @@ Classifications
The string 'undef' 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.
+The string 'undef' 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.
-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.
+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):
+ ++ %A = add %X, undef + %B = sub %X, undef + %C = xor %X, undef +Safe: + %A = undef + %B = undef + %C = undef ++
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.
+ ++ %A = or %X, undef + %B = and %X, undef +Safe: + %A = -1 + %B = 0 +Unsafe: + %A = undef + %B = undef ++
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.
+ ++ %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 ++
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.
+ + ++ %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 ++
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 have a live range. 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.
+