<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 - WebAssembly: Inverting i1 at O0 produces invalid code"
   href="https://bugs.llvm.org/show_bug.cgi?id=38019">38019</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>WebAssembly: Inverting i1 at O0 produces invalid code
          </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>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>dan433584@gmail.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=20507" name="attach_20507" title="IR">attachment 20507</a> <a href="attachment.cgi?id=20507&action=edit" title="IR">[details]</a></span>
IR

First discovered as an innocuous TODO [1] it looks like LLVM's code generation
for i1 may not be valid for WebAssembly when compiling at O0. Starting with
Rust code that looks like:


extern {
    fn return_one() -> u32;
    fn panic() -> !;
}

#[no_mangle]
pub unsafe extern fn test() {
    let tmp: bool = !(return_one() == 1);
    if tmp { panic() }
    if !tmp { panic() }
}


it then generates the attached IR (also linked [2]). When this IR is complied
with:

    llc foo.ll -filetype=obj -o foo.o -O0

it generates this wasm file [3]. The wasm file notably contains:

  (set_local $var$4
   (i32.eq
    (get_local $var$2)
    (get_local $var$3)
   )
  )
  (set_local $var$5
   (i32.const -1)
  )
  (set_local $var$6
   (i32.xor
    (get_local $var$4)
    (get_local $var$5)
   )
  )

which looks like it's equating a variable (correctly) into $var$4, but then it
attempts to invert this variable with an i32.xor instruction which xors either
1 or 0, so the xor of 1 doesn't work (generates 0xfffffffc instead of 0).

I can provide an example running in the browser as well if necessary, but it
may also suffice to say that when run in Firefox the above Rust code executes
successfully! (unexpectedly)

[1]:
<a href="https://github.com/rustwasm/wasm-bindgen/blob/dcb3415da8650b918e5b7f6d65ab071fff7aa6fa/tests/all/webidl/simple.rs#L46-L47">https://github.com/rustwasm/wasm-bindgen/blob/dcb3415da8650b918e5b7f6d65ab071fff7aa6fa/tests/all/webidl/simple.rs#L46-L47</a>
[2]:
<a href="https://gist.github.com/alexcrichton/2baf6f95f00275858c8b81d6eff25327#file-foo-ll">https://gist.github.com/alexcrichton/2baf6f95f00275858c8b81d6eff25327#file-foo-ll</a>
[3]: <a href="https://gist.github.com/alexcrichton/e5cafad8455795aff2c40652fe4d4dc3">https://gist.github.com/alexcrichton/e5cafad8455795aff2c40652fe4d4dc3</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>