<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </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 - MemorySSA doesn't properly invalidate def-def cache entries"
   href="https://bugs.llvm.org/show_bug.cgi?id=36529">36529</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>MemorySSA doesn't properly invalidate def-def cache entries
          </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>All
          </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>Global Analyses
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>george.burgess.iv@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Consider the following code:

define void @foo(i8* %a, i8* %b) {
  ; 1 = MemoryDef(liveOnEntry)
  store i8 0, i8* %a
  ; 2 = MemoryDef(1)
  store i8 0, i8* %b
  ; 3 = MemoryDef(2)
  store i8 0, i8* %a
  ; 4 = MemoryDef(3)
  store i8 0, i8* %b
}

If we use the caching MSSA walker to get the clobbering access of `3` (which is
`1`), we'll cache that result in `3`. If `1` and its corresponding store are
removed from the function -- it's trivially dead, after all -- the cache for
`3` will still be seen as valid, and will still return `1`'s old pointer.

Were we to similarly remove `2`, however, the cache for `3` *would* be properly
invalidated. This is because (I assume) we use "do we have the same store above
us" as a signal for whether the current store has been moved.

This issue does not apply for MemoryUses, since we use operands to do
bookkeeping with those.

The simplest way to fix this seems to be adding an 'optimized' operand to
MemoryDefs, rather than storing 'optimized' as a regular pointer field. Doing
so doesn't loudly break any tests, though I'm unsure if it'll cause functional
changes for existing passes (since with this approach, walking an operands list
for a def now requires extra checks if you don't want to visit every def
twice...). I also don't know offhand how {un,}happy the updater will be with
this. I'll see what I can find out.</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>