Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LLVM-compiled Wasm code produces incorrect result #2143

Closed
HeliosPanoptes opened this issue Feb 27, 2021 · 1 comment · Fixed by #2155
Closed

LLVM-compiled Wasm code produces incorrect result #2143

HeliosPanoptes opened this issue Feb 27, 2021 · 1 comment · Fixed by #2155
Assignees
Labels
bug Something isn't working 🏆 fuzzer-trophy Bugs found automatically by fuzzers. 📦 lib-compiler-llvm About wasmer-compiler-llvm

Comments

@HeliosPanoptes
Copy link

Describe the bug

wasmer 1.0.2 | rustc 1.51.0-nightly (04caa632d 2021-01-30) | x86_64

wat2wasm 1.0.13

Using the llvm compiler can result in a mis-compiled module that produces the wrong result.

(module
  (func $main (result i32)
    i32.const 235
    i32.const -123
    f32.const -1
    f32.const 0
    f32.lt
    i32.rem_u
    i32.rotl)
  (export "_main" (func $main)))

The above Wasm code when compiled and run using LLVM will produce -1, when the expected answer is 235. When the code is compiled and run using Cranelift, the output is as expected.

Steps to reproduce

wasmer_bug.zip

  1. Unzip and go to the root level of the zip file.
  2. Run cargo run ./src/wasmer_bug_minimal.wasm
  3. See that the two compilers produce different results.

Expected behavior

That both the Cranelift-compiled and LLVM-compiled Wasm modules produce the same output.

Actual behavior

The LLVM-compiled module produces -1 as its output, while the Cranelift-compiled module produces 235.

Additional context

None.

@HeliosPanoptes HeliosPanoptes added the bug Something isn't working label Feb 27, 2021
@Hywan Hywan added the 📦 lib-compiler-llvm About wasmer-compiler-llvm label Mar 1, 2021
@nlewycky
Copy link
Contributor

nlewycky commented Mar 1, 2021

Further reduced:

(module
  (func $main (result i32)
    i32.const 235
    i32.const 0
    i32.rotl
  )
  (export "_main" (func $main)))
$ wasmer --llvm test2143.wat -i _main
-1

This is a great bug. LLVM doesn't have a rotate instruction, so we implement it in a few steps with temporary values:

  a = value <<u amt
  b = value >>u (bitwidth - amt)
  c = a | b

where <<u and >>u are "unsigned" or "logical" shifts. However, LLVM defines that shift-right only has defined behaviour if the amount to shift by is from 0..bitwidth-1. When the amount is zero, computing b will attempt to shift by 32 which is not permitted in LLVM IR.

bors bot added a commit that referenced this issue Mar 1, 2021
2155: Correct the implementation of shift and rotate. r=syrusakbary a=nlewycky

Fixes #2143.

Co-authored-by: Nick Lewycky <[email protected]>
@bors bors bot closed this as completed in 3bab215 Mar 2, 2021
@nlewycky nlewycky added the 🏆 fuzzer-trophy Bugs found automatically by fuzzers. label Mar 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working 🏆 fuzzer-trophy Bugs found automatically by fuzzers. 📦 lib-compiler-llvm About wasmer-compiler-llvm
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants