<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 - SCEVExpander wrongly adds nsw to shl instruction"
   href="https://bugs.llvm.org/show_bug.cgi?id=42397">42397</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>SCEVExpander wrongly adds nsw to shl instruction
          </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>Global Analyses
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>pankaj.chawla@intel.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>This SCEVExpander bug was exposed by a recent patch to add nuw/nsw flags when
generating code for SCEVMulExpr.

The test case IR looks like this-

%1 = load i16, i16* %arrayidx
%2 = and i16 %1, -32768

The SCEV form of %2 is this-
(-32768 * (%1 /u -32768))<nuw><nsw>

It has both nsw/nuw flags. The signed range of the second operand of
SCEVMulExpr (%1 /u -32768) is [0, 2). So it can be either 0 or 1.

But SCEVExpander uses shl to generate the multiply. The generated IR looks
something like this-

%7 = lshr i16 %gepload, 15
%8 = shl nuw nsw i16 %7, 15

%8 is later simplified to zero because according to langref it produces poison
otherwise -
If the nuw keyword is present, then the shift produces a poison value if it
shifts out any non-zero bits. If the nsw keyword is present, then the shift
produces a poison value if it shifts out any bits that disagree with the
resultant sign bit.

The shl instruction should not get nsw flag.

Here's instcombine checking for this edge condition when shifting by (bitwidth
- 1) -

<a href="https://github.com/llvm/llvm-project/blob/5e13cd2e61cb187f28d743c15141333530cc1adf/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp#L177">https://github.com/llvm/llvm-project/blob/5e13cd2e61cb187f28d743c15141333530cc1adf/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp#L177</a></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>