[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