[llvm-commits] [llvm] r102479 - /llvm/trunk/docs/LangRef.html

Dan Gohman gohman at apple.com
Tue Apr 27 17:49:41 PDT 2010


Author: djg
Date: Tue Apr 27 19:49:41 2010
New Revision: 102479

URL: http://llvm.org/viewvc/llvm-project?rev=102479&view=rev
Log:
Rewrite the section on trap values to contain a generic description
of dependence and define trap values in terms of dependence, instead
of trying to cover the concept with a flurry of ad-hoc rules.

The dependence model isn't complete yet, but it's already much more
rigorous than the description it replaces.

Modified:
    llvm/trunk/docs/LangRef.html

Modified: llvm/trunk/docs/LangRef.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=102479&r1=102478&r2=102479&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.html (original)
+++ llvm/trunk/docs/LangRef.html Tue Apr 27 19:49:41 2010
@@ -2336,80 +2336,104 @@
    effects has nevertheless detected a condition which results in undefined
    behavior.</p>
 
-<p>Any value other than a non-intrinsic call, invoke, or phi with a trap
-   operand has trap as its result value.  Any instruction with
-   a trap operand which may have side effects emits those side effects as
-   if it had an undef operand instead. If the side effects are externally
-   visible, the behavior is undefined.</p>
+<p>There is currently no way of representing a trap value in the IR; they
+   only exist when produced by instructions such as
+   <a href="#i_add"><tt>add</tt></a> with the <tt>nsw</tt> flag.</p>
 
-<p>Trap values may be stored to memory; a load from memory including any
-   part of a trap value results in a (full) trap value.</p>
-   
-<p>For example:</p>
+<p>Trap value behavior is defined in terms of value <i>dependence</i>:</p>
+
+<p>
+<ul>
+<li>Values other than <a href="#i_phi"><tt>phi</tt></a> nodes depend on
+    their operands.</li>
+
+<li><a href="#i_phi"><tt>Phi</tt></a> nodes depend on the operand corresponding
+    to their dynamic predecessor basic block.</li>
+
+<li>Function arguments depend on the corresponding actual argument values in
+    the dynamic callers of their functions.</li>
+
+<li><a href="#i_call"><tt>Call</tt></a> instructions depend on the
+    <a href="#i_ret"><tt>ret</tt></a> instructions that dynamically transfer
+    control back to them.</li>
 
-<!-- FIXME: In the case of multiple threads, this only applies to loads from
-     the same thread as the store, or loads which are sequenced after the
+<li>Non-volatile loads and stores depend on the most recent stores to all of the
+    referenced memory addresses, following the order in the IR
+    (including loads and stores implied by intrinsics such as
+    <a href="#int_memcpy"><tt>@llvm.memcpy</tt></a>.)</li>
+
+<!-- FIXME: padding in the middle of a struct -->
+
+<!-- TODO: In the case of multiple threads, this only applies to loads and
+     stores from the same thread as the store, or which are sequenced after the
      store by synchronization. -->
 
-<div class="doc_code">
-<pre>
-%trap = sub nuw i32 0, 1           ; Results in a trap value.
-%still_trap = and i32 %trap, 0     ; Whereas (and i32 undef, 0) would return 0.
-%trap_yet_again = getelementptr i32* @h, i32 %still_trap
-store i32 0, i32* %trap_yet_again  ; undefined behavior
-
-volatile store i32 %trap, i32* @g  ; External observation; undefined behavior.
-%trap2 = load i32* @g              ; Returns a trap value, not just undef.
-%narrowaddr = bitcast i32* @g to i16*
-%wideaddr = bitcast i32* @g to i64*
-%trap3 = load 16* %narrowaddr      ; Returns a trap value
-%trap4 = load i64* %widaddr        ; Returns a trap value, not partial trap.
-</pre>
-</div>
+<!-- TODO: floating-point exception state -->
 
-<p>If a <a href="#i_br"><tt>br</tt></a> or
-   <a href="#i_switch"><tt>switch</tt></a> instruction has a trap value
-   operand, all non-phi non-void instructions which control-depend on it
-   have trap as their result value. A <a href="#i_phi"><tt>phi</tt></a>
-   node with an incoming value associated with a control edge which is
-   control-dependent on it has trap as its result value when control is
-   transferred from that block.  If any instruction which control-depends
-   on the <tt>br</tt> or <tt>switch</tt> invokes externally visible side
-   effects, the behavior of the program is undefined. For example:</p>
+<li>An instruction with externally visible side effects depends on the most
+    recent preceding instruction with externally visible side effects, following
+    the order in the IR. (This includes volatile loads and stores.)</li>
+
+<li>An instruction <i>control-depends</i> on a <a href="#i_br"><tt>br</tt></a>,
+    <a href="#i_switch"><tt>switch</tt></a>, or
+    <a href="#i_indirectbr"><tt>indirectbr</tt></a> if the <tt>br</tt>,
+    <tt>switch</tt>, or <tt>indirectbr</tt> has multiple successors and the
+    instruction is always executed when control transfers to one of the
+    successors, and may not be executed when control is transfered to
+    another.</li>
 
-<!-- FIXME: What about exceptions thrown from control-dependent instrs? -->
+<!-- FIXME: invoke, unwind, exceptions -->
+
+<li>Dependence is transitive.</li>
+
+</ul>
+</p>
+
+<p>Whenever a trap value is generated, all values which depend on it evaluate
+   to trap. If they have side effects, the evoke their side effects as if each
+   operand with a trap value were undef. If they have externally-visible side
+   effects, the behavior is undefined.</p>
+
+<p>Here are some examples:</p>
 
 <div class="doc_code">
 <pre>
 entry:
   %trap = sub nuw i32 0, 1           ; Results in a trap value.
-  %cmp = icmp i32 slt %trap, 0       ; Still trap.
+  %still_trap = and i32 %trap, 0     ; Whereas (and i32 undef, 0) would return 0.
+  %trap_yet_again = getelementptr i32* @h, i32 %still_trap
+  store i32 0, i32* %trap_yet_again  ; undefined behavior
+
+  store i32 %trap, i32* @g           ; Trap value conceptually stored to memory.
+  %trap2 = load i32* @g              ; Returns a trap value, not just undef.
+
+  volatile store i32 %trap, i32* @g  ; External observation; undefined behavior.
+
+  %narrowaddr = bitcast i32* @g to i16*
+  %wideaddr = bitcast i32* @g to i64*
+  %trap3 = load 16* %narrowaddr      ; Returns a trap value.
+  %trap4 = load i64* %widaddr        ; Returns a trap value.
+
+  %cmp = icmp i32 slt %trap, 0       ; Returns a trap value.
   %br i1 %cmp, %true, %end           ; Branch to either destination.
 
 true:
-  volatile store i32 0, i32* @g      ; Externally visible side effects
-                                     ; control-dependent on %cmp.
-                                     ; Undefined behavior.
+  volatile store i32 0, i32* @g      ; This is control-dependent on %cmp, so
+                                     ; it has undefined behavior.
   br label %end
 
 end:
   %p = phi i32 [ 0, %entry ], [ 1, %true ]
                                      ; Both edges into this PHI are
                                      ; control-dependent on %cmp, so this
-                                     ; results in a trap value.
+                                     ; always results in a trap value.
 
   volatile store i32 0, i32* @g      ; %end is control-equivalent to %entry
                                      ; so this is defined (ignoring earlier
                                      ; undefined behavior in this example).
-
 </pre>
 </div>
 
-<p>There is currently no way of representing a trap constant in the IR; they
-   only exist when produced by certain instructions, such as an
-   <a href="#i_add"><tt>add</tt></a> with the <tt>nsw</tt> flag
-   set, when overflow occurs.</p>
-
 </div>
 
 <!-- ======================================================================= -->





More information about the llvm-commits mailing list