[llvm-commits] [PATCH] Trap values persist through memory and cause undefined switch behavior (issue946042)

jyasskin at gmail.com jyasskin at gmail.com
Sun Apr 25 00:49:07 PDT 2010


Reviewers: llvm-commits_cs.uiuc.edu, gohman_apple.com,

Message:
We noticed this when designing the concurrency memory model, but I think
it's a needed refinement regardless.

Description:
Clarify that a trap value stored to memory stays a trap value after it's
loaded back into a register, even though the side effect (for example,
from a volatile store) is still undef.

Also extend trap values to cause undefined behavior when they control a
conditional branch or switch. This is important for switches because it
can allow the optimizer to change the default branch to unreachable. If
a trap switch argument merely acted like undef, the optimizers couldn't
introduce a branch to unreachable.  I'm less sure that br(trap) needs to
be unreachable, but it seems nicely symmetric.

Please review this at http://codereview.appspot.com/946042/show

Affected files:
   M     docs/LangRef.html


Index: docs/LangRef.html
===================================================================
--- docs/LangRef.html	(revision 102303)
+++ docs/LangRef.html	(working copy)
@@ -2307,23 +2307,34 @@
  <div class="doc_subsection"><a name="trapvalues">Trap Values</a></div>
  <div class="doc_text">

-<p>Trap values are similar to <a href="undefvalues">undef values</a>,  
however
+<p>Trap values are similar to <a href="#undefvalues">undef values</a>,  
however
     instead of representing an unspecified bit pattern, they represent the
     fact that an instruction or constant expression which cannot evoke side
     effects has nevertheless detected a condition which results in undefined
-   behavior.<p>
+   behavior.</p>

  <p>Any non-void instruction or constant expression 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.</p>
+   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.  Notwithstanding that, a  
store
+   of a trap value causes subsequent loads of the same memory to return a  
trap
+   value.  For example:</p>

-<p>For example, an <a href="#i_and"><tt>and</tt></a> of a trap value with
-   zero still has a trap value result. Using that value as an index in a
-   <a href="#i_getelementptr"><tt>getelementptr</tt></a> yields a trap
-   result. Using that result as the address of a
-   <a href="#i_store"><tt>store</tt></a> produces undefined behavior.</p>
+<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 observations of @g see undef.
+%trap2 = load i32* @g  ; Returns a trap value, not just undef.
+</pre>
+</div>
+
+<p>A <a href="#i_br">br</a> or <a href="#i_switch">switch</a> instruction  
whose
+   control operand is a trap value results in undefined behavior.</p>
+
  <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





More information about the llvm-commits mailing list