<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 - Should CorrelatedValuePropagation pass reduce width of shifts?"
   href="https://bugs.llvm.org/show_bug.cgi?id=42746">42746</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Should CorrelatedValuePropagation pass reduce width of shifts?
          </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>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>lebedev.ri@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>I'm currently looking into re-fixing
<a class="bz_bug_link 
          bz_status_REOPENED "
   title="REOPENED - InstCombine: shift amount reassociation when doing bit test"
   href="show_bug.cgi?id=42399">https://bugs.llvm.org/show_bug.cgi?id=42399</a>,
and i'm currently stuck with a pattern like:

define i1 @test(i64 %storage, i32 %nbits) {
  %skipnbits = sub nsw i32 64, %nbits
  %skipnbitswide = zext i32 %skipnbits to i64
  %datawide = lshr i64 %storage, %skipnbitswide
  %data = trunc i64 %datawide to i32
  %nbitsminusone = add nsw i32 %nbits, -1
  %bitmask = shl i32 1, %nbitsminusone
  %bitmasked = and i32 %bitmask, %data
  %isbitunset = icmp eq i32 %bitmasked, 0
  ret i1 %isbitunset
}

While the desired optimized result is:
define i1 @test(i64 %storage, i32 %nbits) {
  %tmp = icmp sgt i64 %storage, -1
  ret i1 %tmp
}

That transform is indeed correct:
Name: PR42399
  %skipnbits = sub nsw i32 64, %nbits
  %skipnbitswide = zext i32 %skipnbits to i64
  %datawide = lshr i64 %storage, %skipnbitswide
  %data = trunc i64 %datawide to i32
  %nbitsminusone = add nsw i32 %nbits, -1
  %bitmask = shl i32 1, %nbitsminusone
  %bitmasked = and i32 %bitmask, %data
  %isbitunset = icmp eq i32 %bitmasked, 0
=>
  %isbitunset = icmp sgt i64 %storage, -1

<a href="https://rise4fun.com/Alive/hUu">https://rise4fun.com/Alive/hUu</a>


The problem is those truncations around shifts.
The current legality check i've come up with is:
<a href="https://rise4fun.com/Alive/M5vF">https://rise4fun.com/Alive/M5vF</a>

Name: one truncation 0 - the original widest input should be losslessly
truncatable, or the other input should be '1'
Pre: C1+C2 u< 64 && ( (countLeadingZeros(C11) u>= (64-32)) ||
(countLeadingZeros(C22) u>= (32-1)) )
  %C1_64 = zext i8 C1 to i64
  %C2_32 = zext i8 C2 to i32
  %old_shift_of_x = lshr i64 C11, %C1_64
  %old_shift_of_y = shl i32 C22, %C2_32
  %old_trunc_of_shift_of_x = trunc i64 %old_shift_of_x to i32
  %old_masked = and i32 %old_trunc_of_shift_of_x, %old_shift_of_y
  %r = icmp ne i32 %old_masked, 0
=>
  %C1_64 = zext i8 C1 to i64
  %C2_64 = zext i8 C2 to i64
  %new_shamt = add i64 %C1_64, %C2_64
  %new_y_wide = zext i32 C22 to i64
  %new_shift = shl i64 %new_y_wide, %new_shamt  
  %new_masked = and i64 %new_shift, C11
  %r = icmp ne i64 %new_masked, 0

I.e. the transform can be done if the truncation could have been threaded over
the shift
in the first place.
But we don't seem to do that currently, and we don't do the opposite transform:
<a href="https://godbolt.org/z/qYlMJP">https://godbolt.org/z/qYlMJP</a>

In CorrelatedValuePropagation.cpp i only see reduction of udiv/urem width.
Should it be taught to also reduce width of shifts?</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>