On Apr 12, 2011, at 9:59 AM, Jianzhou Zhao wrote:
> Hi,
>
> I am trying to understand trapvalues
> http://llvm.org/docs/LangRef.html#trapvalues
> My question is that how LLVM expects to use trapvalues. Should we track if
a value is trapped or not at runtime or statically? One rule (for terminator
instruction) that defines a trap value is
>
> # An instruction control-depends on a terminator instruction if the
terminator instruction 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.
>
> But, at runtime, it seems difficult to know if an instruction "may not
be executed when control is transfered to another." For example of the code
given on the webpage.
>
> entry:
> ...
> %br i1 %cmp, %true, %end ; Branch to either destination.
>
> true:
> ...
> br label %end
>
> end:
> ...
> volatile store i32 0, i32* @g ; %end is control-equivalent to %entry
> ; so this is defined (ignoring
earlier
> ; undefined behavior in this
example).
>
> Statically, we can see the store in the end block is not trapped since it
always runs no matter what value %cmp is. But at runtime, we may have to keep
track of the code's CFG.
Yes. I believe fully precise trap tracking would require a
highly elaborate combination of static and dynamic analysis,
and at the whole-program level.
>
> On other hand, the rules for Phi nodes/Arguments/Calls are defined in terms
of dynamic states for preciseness.
>
> #Phi nodes depend on the operand corresponding to their dynamic predecessor
basic block.
> #Function arguments depend on the corresponding actual argument values in
the dynamic callers of their functions.
> #Call instructions depend on the ret instructions that dynamically transfer
control back to them.
>
> I think Function arguments and calls are fine to keep track at runtime. But
Phi nodes have the same problem as the terminator instruction rule. My confusion
is the operational meaning of trapvalues.
The main intuition for trap values is that they can occur on
speculative code paths, and if a speculative path is discarded,
its trap values are harmlessly discarded as well. But if a trap
value reaches a non-speculative path, it triggers actual
undefined behavior.
It's unfortunate that this simple concept ended up being so
hard to verify dynamically. But, for example, dependencies have
to be fully precise even across things like call boundaries,
because neither inlining nor outlining should be able to change
program semantics. Perhaps it would be practical to develop a
conservative tracker which could catch common problems though.
Dan