<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 - wasm32: i8x16.bitmask return value assumes upper 16 bits may not be zero"
   href="https://bugs.llvm.org/show_bug.cgi?id=50507">50507</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>wasm32: i8x16.bitmask return value assumes upper 16 bits may not be zero
          </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>Backend: WebAssembly
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>alex@crichton.co
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>In the course of binding the i8x16.bitmask instruction for Rust some discussion
-- <a href="https://github.com/rust-lang/rust/issues/74372#issuecomment-848543931">https://github.com/rust-lang/rust/issues/74372#issuecomment-848543931</a> --
brought up that an appropriate return value for this intrinsic would be u16
since it can only return 16 bits of data (and u8 for the other bitmask
intrinsics). When changing the intrinsics to do this, though, it generates an
unnecessary i32.and instruction to mask out the upper bits.

I believe the reason for this is that the intrinsics are declared in LLVM as
returning an i32 so when we cast that to an i16 in LLVM IR it causes the
general codegen mechanism for such a cast to kick in which masks away the upper
bits.

Basically this IR:


target triple = "wasm32"

declare i32 @llvm.wasm.bitmask.v16i8(<16 x i8>)

define zeroext i16 @foo(<4 x i32> %a) unnamed_addr #0 {
start:
  %0 = bitcast <4 x i32> %a to <16 x i8>
  %1 = tail call i32 @llvm.wasm.bitmask.v16i8(<16 x i8> %0)
  %2 = trunc i32 %1 to i16
  ret i16 %2
}

attributes #0 = { "target-features"="+simd128" }



produces (expectedly) the sequence:


        i8x16.bitmask
        i32.const       65535
        i32.and 


Could the intrisnic, however, be modified to return `i16`? Simlarly could the
other intrinsics be updated to return `i8`? I'm not sure if `i4` is well
supported but presumably if it works it could be used for `i32x4.bitmask`,
although for language binding purposes it'd be nice to also accept `i8` as a
return value for the intrinsic.</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>