<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] Miscompile (?) of select with poison case"
   href="https://bugs.llvm.org/show_bug.cgi?id=48435">48435</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[InstCombine] Miscompile (?) of select with poison case
          </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>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>meheff@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>I'm not totally sure this is a bug as I don't know the semantics of a select
which has a poison value in the non-selected position. Anyway, the input is
basically a shift followed by select with some other cruft. The select guards
against use of an overshifted value by selecting zero in the case of overshift.

Input:

define i1 @test() local_unnamed_addr {
so_basic:
  %x5 = call i32 @f(i32 100)
  %ne_42 = icmp ne i32 %x5, 0
  %_z3 = zext i32 %x5 to i64
  %_z4 = icmp uge i64 %_z3, 64
  %_z5 = lshr i64 256, %_z3
  %_z6 = trunc i64 %_z5 to i32
  %x15 = select i1 %_z4, i32 0, i32 %_z6
  %ne_44 = icmp ne i32 %x15, 0
  %x18 = or i1 %ne_42, %ne_44
  ret i1 %x18
}

define i32 @f(i32 %x) {
  ret i32 %x
}


Result of opt -O2:


define i1 @test() local_unnamed_addr #0 {
so_basic:
  ret i1 poison
}


Looks like the problematic xform replaces the select(p, false, x) with
and(not(p), x) where x is poison in this case.


Alive:

----------------------------------------
define i1 @src() {
%0:
  %x5 = call i32 @f(i32 100)
  %ne_42 = icmp ne i32 %x5, 0
  %_z3 = zext i32 %x5 to i64
  %_z4 = icmp ugt i32 %x5, 63
  %_z5 = lshr i64 256, %_z3
  %_z6 = trunc i64 %_z5 to i32
  %ne_441 = icmp ne i32 %_z6, 0
  %not._z4 = xor i1 %_z4, 1
  %ne_44 = and i1 %not._z4, %ne_441
  %x18 = or i1 %ne_42, %ne_44
  ret i1 %x18
}
=>
define i1 @tgt() {
%0:
  ret i1 poison
}
Transformation doesn't verify!
ERROR: Target is more poisonous than source

Example:

Source:
i32 %x5 = #x00000000 (0)
i1 %ne_42 = #x0 (0)
i64 %_z3 = #x0000000000000000 (0)
i1 %_z4 = #x0 (0)
i64 %_z5 = #x0000000000000100 (256)
i32 %_z6 = #x00000100 (256)
i1 %ne_441 = #x1 (1)
i1 %not._z4 = #x1 (1)
i1 %ne_44 = #x1 (1)
i1 %x18 = #x1 (1)

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >       size: 0 align: 1        alloc type: 0
Block 1 >       size: 0 align: 2        alloc type: 0

Target:
Source value: #x1 (1)
Target value: poison</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>