<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 - InstCombine unable to optimize away unnecessary sign extension having multiple use"
   href="https://bugs.llvm.org/show_bug.cgi?id=47765">47765</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>InstCombine unable to optimize away unnecessary sign extension having multiple use
          </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>bhramar.vatsa@synopsys.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The following code (shortened/adapted from real code):

long long foo(const long long a, int b, short c, int d)
{
    const bool odd = b % 2;

    d = (short)d;
    if (odd) {
        d = (d & 0x03ff) | (c << 8);
        d += (d * 3) + 45333;
    } else {
        d = (d & 0x3fc0) | (c << 12);
        d += (d * 4) + 65333;
    }

    return a & d;
}

Results in following IR:

...
  %7 = shl i32 %3, 16, !dbg !26               <-- Can be removed
  %8 = ashr exact i32 %7, 16, !dbg !26        <-- Can be removed
  br i1 %6, label %16, label %9, !dbg !28

9:                                                ; preds = %4
  %10 = and i32 %8, 1023, !dbg !29
  ...
16:                                               ; preds = %4
  %17 = and i32 %8, 16320, !dbg !37

It can also be seen at: <a href="https://godbolt.org/z/PoqM67">https://godbolt.org/z/PoqM67</a>

Here, the truncation/sign-extension code (%3 -> %8) has use within the
then-else blocks (Labels 9 & 16). However, the 'and' instructions only results
in usage of lower 16 bits (actually maximum 14 LSBs). So, the 'shl' and 'ashr'
instructions can be optimized away without any impact whatsoever on the
functionality.

The place for such an optimization is within InstCombine pass
(InstCombiner::visitAnd() -> InstCombiner::SimplifyDemandedUseBits()). It
doesn't happen though, due to the fact that when the information about the
demanded bits is passed onto 'ashr' instruction (through the worklist), it
finds that the 'ashr' instruction has multiple use and that restricts it from
making an optimization (removal of trunc/sext operation).

It should be noted that if the code to trunc/sext ('(short)d') is pushed within
then/else block, (post-bb7d3af11 commit) the optimization takes place. So, the
same 'InstCombine' transformation is able to optimize away these operations
from then/else blocks.

Since the optimization happens with the non-hoisted example, it should be
possible in some way to make it work even with hoisted code.</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>