<html>
<head>
<base href="https://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW --- - [Statepoint] Dangling pointer in RS4GC"
href="https://llvm.org/bugs/show_bug.cgi?id=25846">25846</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[Statepoint] Dangling pointer in RS4GC
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Scalar Optimizations
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>me@manueljacob.de
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=15459" name="attach_15459" title="Example IR, exposing the bug">attachment 15459</a> <a href="attachment.cgi?id=15459&action=edit" title="Example IR, exposing the bug">[details]</a></span>
Example IR, exposing the bug
In RS4GC, ReplaceBaseInstWith() deletes an instruction without removing it from
the `States` mapping sometimes. I've attached a crashing example and two
patches, applying *one* of them is sufficient to make the dangling pointer show
up early. Otherwise the dangling pointer will get into the cache, crashing
`opt` at some later point nondeterministically.
You can reproduce it by: opt -spp-no-entry -spp-no-backedge -place-safepoints
-rewrite-statepoints-for-gc test.ll
Here's why I think it fails:
0) `States` before first call of ReplaceBaseInstWith():
%phi1 -> %phi1.base [won't change, omitted below]
%select1 -> %select1.base
%select2 -> %select2.base
1) ReplaceBaseInstWith() is called with BDV = %select2, BaseI = %select2.base,
Replacement = %select1.base, because simplify(%select2.base) = %select1.base
%select1 -> %select1.base
%select2 -> %select1.base
2) ReplaceBaseInstWith() is called with BDV = %select1, BaseI = %select1.base,
Replacement = %select1, because %select1.base is "identical" to %select1
%select1 -> %select1
%select2 -> %select1.base
Now deleting %select1.base is wrong because it's still in `States`.
The code assumes (`ReverseMap`) that `States`'s BDV -> base mapping is
injective, but it's not after 1). Therefore it's not sufficient to replace
only the BDV -> BaseI entry with BDV -> Replacement, since multiple BDVs (and
not only the one from `ReverseMap`) might map to BaseI.
Instructions:
%select1 = select i1 undef, i8 addrspace(1)* %in1, i8 addrspace(1)* %in2
%select1.base = select i1 undef, i8 addrspace(1)* %in1, i8 addrspace(1)* %in2,
!is_base_value !0
%select2 = select i1 undef, i8 addrspace(1)* %select1, i8 addrspace(1)*
%select1
%select2.base = select i1 undef, i8 addrspace(1)* %select1.base, i8
addrspace(1)* %select1.base, !is_base_value !0</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>