From 34b3d993e46230b9ba1d1d5dccda89eb09cebe60 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Apr 2010 00:49:41 +0000 Subject: [PATCH] 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 --- docs/LangRef.html | 116 ++++++++++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 46 deletions(-) diff --git a/docs/LangRef.html b/docs/LangRef.html index f828b380777..aa6b797837c 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -2336,80 +2336,104 @@ has undefined behavior.

effects has nevertheless detected a condition which results in undefined behavior.

-

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.

+

There is currently no way of representing a trap value in the IR; they + only exist when produced by instructions such as + add with the nsw flag.

-

Trap values may be stored to memory; a load from memory including any - part of a trap value results in a (full) trap value.

- -

For example:

+

Trap value behavior is defined in terms of value dependence:

- + + -
-
-%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.
-
-
+
  • 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.)
  • -

    If a br or - switch instruction has a trap value - operand, all non-phi non-void instructions which control-depend on it - have trap as their result value. A phi - 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 br or switch invokes externally visible side - effects, the behavior of the program is undefined. For example:

    +
  • An instruction control-depends on a br, + switch, or + indirectbr if the br, + switch, or indirectbr 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.
  • - + + +
  • Dependence is transitive.
  • + + +

    + +

    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.

    + +

    Here are some examples:

     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).
    -
     
    -

    There is currently no way of representing a trap constant in the IR; they - only exist when produced by certain instructions, such as an - add with the nsw flag - set, when overflow occurs.

    -