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