describe undef semantics in some more detail.
llvm-svn: 81167
This commit is contained in:
		
							parent
							
								
									02e363ed52
								
							
						
					
					
						commit
						ec72b9bbcf
					
				| 
						 | 
					@ -2016,12 +2016,108 @@ Classifications</a> </div>
 | 
				
			||||||
<div class="doc_subsection"><a name="undefvalues">Undefined Values</a></div>
 | 
					<div class="doc_subsection"><a name="undefvalues">Undefined Values</a></div>
 | 
				
			||||||
<div class="doc_text">
 | 
					<div class="doc_text">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<p>The string '<tt>undef</tt>' is recognized as a type-less constant that has no
 | 
					<p>The string '<tt>undef</tt>' can be used anywhere a constant is expected, and
 | 
				
			||||||
   specific value.  Undefined values may be of any type and be used anywhere a
 | 
					   indicates that the user of the value may recieve an unspecified bit-pattern.
 | 
				
			||||||
   constant is permitted.</p>
 | 
					   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
 | 
					<p>Undefined values are useful, because it indicates to the compiler that the
 | 
				
			||||||
   matter what value is used, giving the compiler more freedom to optimize.</p>
 | 
					   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>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue