<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 - Funnel shift simplification based on demanded bits fails on multiple uses"
   href="https://bugs.llvm.org/show_bug.cgi?id=39771">39771</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Funnel shift simplification based on demanded bits fails on multiple uses
          </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>Windows NT
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </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>nikita.ppv@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre><a href="https://reviews.llvm.org/D54869">https://reviews.llvm.org/D54869</a> added InstCombine simplification for funnel
shifts based on demanded bits. However, the original motivating case from Rust
(<a href="https://github.com/rust-lang/rust/issues/56009">https://github.com/rust-lang/rust/issues/56009</a>) is not solved by this. A
reduced test case for this issue is given in the following and also present in
test/Transforms/InstCombine/fsh.ll:

declare i33 @llvm.fshr.i33(i33, i33, i33)

define i33 @fshr_multi_use(i33 %a) {
  %b = tail call i33 @llvm.fshr.i33(i33 %a, i33 %a, i33 1)
  %c = lshr i33 %b, 23
  %d = xor i33 %c, %b
  %e = and i33 %d, 31
  ret i33 %e
}

The expected simplification is:

define i33 @fshr_multi_use(i33 %a) {
  %b = lshr i33 %a, 1 
  %c = lshr i33 %a, 24
  %d = xor i33 %c, %b
  %e = and i33 %d, 31
  ret i33 %e
}

If the funnel shift is written explicitly as shifts+or, as in the following,
the simplification does take place:

define i33 @expanded_fshr_multi_use(i33 %a) {
  %tmp = lshr i33 %a, 1
  %tmp2 = shl i33 %a, 32
  %b = or i33 %tmp, %tmp2
  %c = lshr i33 %b, 23
  %d = xor i33 %c, %b
  %e = and i33 %d, 31
  ret i33 %e
}

InstCombine demanded bits simplifications generally only work if the
instruction has a single use. Only for or/and/xor multiple uses are handled, in
which case the operation may be reduced to one of its operands in some cases
(which happens here).

An alternative place where such a simplification could take place is BDCE,
which is based on the DemandedBits analysis. This will successfully handle
multiple uses, but exhibits a different issue: Demanded bits are only tracked
on the instruction level. If funnel shifts are used for rotates, then the first
two operands will be the same, and the demanded bits for both operands will be
combined, preventing this kind of simplification.</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>