diff options
author | Dan Gohman <gohman@apple.com> | 2010-04-28 00:49:41 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2010-04-28 00:49:41 +0000 |
commit | 34b3d993e46230b9ba1d1d5dccda89eb09cebe60 (patch) | |
tree | 810ed1826e2814ecbffb661e6ce34bf0a309013b /docs/LangRef.html | |
parent | 1c70c00c285083b335ab7518917dac27bc282f24 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102479 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'docs/LangRef.html')
-rw-r--r-- | docs/LangRef.html | 118 |
1 files changed, 71 insertions, 47 deletions
diff --git a/docs/LangRef.html b/docs/LangRef.html index f828b38077..aa6b797837 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -2336,80 +2336,104 @@ has undefined behavior.</p> 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>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>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 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 +<!-- TODO: floating-point exception state --> -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> +<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> -<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 <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> <!-- ======================================================================= --> |