Open kazcw opened 5 years ago
I don't see how this could be anything but a rustc codegen / wasm intrinsics bug, but I haven't been able to reproduce it without building with cargo-web.
Definitely looks like a codegen bug. A simpler repro:
#![no_std]
#![feature(start)]
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
loop {}
}
#[start]
fn main(_: isize, _: *const *const u8) -> isize {
1u128.rotate_right(1);
0
}
This produces the following (in debug mode):
(module
(type (;0;) (func))
(type (;1;) (func (param i32 i64 i64 i32)))
(type (;2;) (func (param i32 i32) (result i32)))
(import "env" "__web_on_grow" (func $__web_on_grow (type 0)))
(func $__wasm_call_ctors (type 0))
(func $_ZN4core3num22_$LT$impl$u20$u128$GT$12rotate_right17h9dd638bf1db6bc5aE (type 1) (param i32 i64 i64 i32)
(local i32 i32 i32 i64 i64 i64 i64 i64 i64 i32 i32 i64 i64 i32 i32 i64 i64 i64 i32 i32 i32 i32 i64 i32 i32 i32 i64 i64 i64 i64 i32 i32)
get_global 0
set_local 4
i32.const 80
set_local 5
get_local 4
get_local 5
i32.sub
set_local 6
get_local 6
set_global 0
get_local 6
get_local 1
i64.store offset=40
get_local 6
get_local 2
i64.store offset=48
get_local 6
get_local 3
i32.store offset=60
get_local 6
i64.load offset=48
set_local 7
get_local 6
i64.load offset=40
set_local 8
get_local 6
i64.load32_u offset=60
set_local 9
i64.const 127
set_local 10
get_local 9
get_local 10
i64.and
set_local 11
i64.const 0
set_local 12
i32.const 24
set_local 13
get_local 6
get_local 13
i32.add
set_local 14
get_local 14
get_local 8
get_local 7
get_local 11
get_local 12
call $_ZN17compiler_builtins3int5shift13rust_u128_shr17h13bc89a30fced34aE
get_local 12
get_local 9
i64.sub
set_local 15
get_local 15
get_local 10
i64.and
set_local 16
i32.const 8
set_local 17
get_local 6
get_local 17
i32.add
set_local 18
get_local 18
get_local 8
get_local 7
get_local 16
get_local 12
call $_ZN17compiler_builtins3int5shift13rust_i128_shl17h15ab07cc5d615a82E
get_local 6
i64.load offset=24 align=1
set_local 19
get_local 6
i64.load offset=8 align=1
set_local 20
get_local 20
get_local 19
i64.or
set_local 21
i32.const 8
set_local 22
i32.const 24
set_local 23
get_local 6
get_local 23
i32.add
set_local 24
get_local 24
get_local 22
i32.add
set_local 25
get_local 25
i64.load align=1
set_local 26
i32.const 8
set_local 27
get_local 6
get_local 27
i32.add
set_local 28
get_local 28
get_local 22
i32.add
set_local 29
get_local 29
i64.load align=1
set_local 30
get_local 30
get_local 26
i64.or
set_local 31
get_local 6
get_local 31
i64.store offset=72
get_local 6
get_local 21
i64.store offset=64
get_local 6
i64.load offset=72
set_local 32
get_local 6
i64.load offset=64
set_local 33
get_local 0
get_local 33
i64.store
get_local 0
get_local 32
i64.store offset=8
i32.const 80
set_local 34
get_local 6
get_local 34
i32.add
set_local 35
get_local 35
set_global 0
return)
(func $_ZN6foobar4main17h153e5080d7c41a58E (type 2) (param i32 i32) (result i32)
(local i32 i32 i32 i32 i64 i64 i32 i32 i32 i32 i32)
get_global 0
set_local 2
i32.const 32
set_local 3
get_local 2
get_local 3
i32.sub
set_local 4
get_local 4
set_global 0
get_local 4
get_local 0
i32.store offset=24
get_local 4
get_local 1
i32.store offset=28
i32.const 1
set_local 5
i64.const 0
set_local 6
i64.const 1
set_local 7
i32.const 8
set_local 8
get_local 4
get_local 8
i32.add
set_local 9
get_local 9
get_local 7
get_local 6
get_local 5
call $_ZN4core3num22_$LT$impl$u20$u128$GT$12rotate_right17h9dd638bf1db6bc5aE
i32.const 0
set_local 10
i32.const 32
set_local 11
get_local 4
get_local 11
i32.add
set_local 12
get_local 12
set_global 0
get_local 10
return)
(func $main (type 2) (param i32 i32) (result i32)
(local i32 i32)
i32.const 0
set_local 2
get_local 2
i32.load8_u offset=1048576
drop
get_local 0
get_local 1
call $_ZN6foobar4main17h153e5080d7c41a58E
set_local 3
get_local 3
return)
(func $_ZN17compiler_builtins3int5shift13rust_i128_shl17h15ab07cc5d615a82E (type 1) (param i32 i64 i64 i32)
(local i64)
block ;; label = @1
block ;; label = @2
get_local 3
i32.const 64
i32.and
br_if 0 (;@2;)
get_local 3
i32.eqz
br_if 1 (;@1;)
get_local 1
i32.const 0
get_local 3
i32.sub
i32.const 63
i32.and
i64.extend_u/i32
i64.shr_u
get_local 2
get_local 3
i32.const 63
i32.and
i64.extend_u/i32
tee_local 4
i64.shl
i64.or
set_local 2
get_local 1
get_local 4
i64.shl
set_local 1
br 1 (;@1;)
end
get_local 1
get_local 3
i32.const 63
i32.and
i64.extend_u/i32
i64.shl
set_local 2
i64.const 0
set_local 1
end
get_local 0
get_local 1
i64.store
get_local 0
get_local 2
i64.store offset=8)
(func $_ZN17compiler_builtins3int5shift13rust_u128_shr17h13bc89a30fced34aE (type 1) (param i32 i64 i64 i32)
(local i64)
block ;; label = @1
block ;; label = @2
get_local 3
i32.const 64
i32.and
br_if 0 (;@2;)
get_local 3
i32.eqz
br_if 1 (;@1;)
get_local 1
get_local 3
i32.const 63
i32.and
i64.extend_u/i32
tee_local 4
i64.shr_u
get_local 2
i32.const 0
get_local 3
i32.sub
i32.const 63
i32.and
i64.extend_u/i32
i64.shl
i64.or
set_local 1
get_local 2
get_local 4
i64.shr_u
set_local 2
br 1 (;@1;)
end
get_local 2
get_local 3
i32.const 63
i32.and
i64.extend_u/i32
i64.shr_u
set_local 1
i64.const 0
set_local 2
end
get_local 0
get_local 1
i64.store
get_local 0
get_local 2
i64.store offset=8)
(table (;0;) 1 1 anyfunc)
(memory (;0;) 17)
(global (;0;) (mut i32) (i32.const 1048576))
(global (;1;) i32 (i32.const 1048610))
(global (;2;) i32 (i32.const 1048610))
(global (;3;) i32 (i32.const 1048576))
(export "main" (func $main))
(export "__indirect_function_table" (table 0))
(export "memory" (memory 0))
(export "__heap_base" (global 1))
(export "__data_end" (global 2))
(export "__rustc_debug_gdb_scripts_section__" (global 3))
(data (i32.const 1048576) "\01gdb_load_rust_pretty_printers.py\00"))
and fails validation:
target/wasm32-unknown-unknown/debug/foobar.wasm:000015f: error: type mismatch in call, expected [i32, i64, i64, i32] but got [... i64, i64, i64, i64]
target/wasm32-unknown-unknown/debug/foobar.wasm:0000184: error: type mismatch in call, expected [i32, i64, i64, i32] but got [... i64, i64, i64, i64]
It reproduces easily without cargo-web
. Just compile it once to have cargo-web
generate the .js
file for you, then grab it, delete target
, recompile with cargo build --target=wasm32-unknown-unknown
and launch it throgh Node.js using the .js
file you've saved.
Great. Kicking this further up the toolchain: rust-lang/rust#61521
FYI, upstream issue has been rejected as @alexcrichton doesn't think it looks like a Rust or LLVM bug. All I know is it's not my bug; I no longer rotate u128s in portable crates.
src/main.rs:
cargo web test --target=wasm32-unknown-unknown:
Other u128 ops besides rotate_left/right are fine.
If I just
cargo build --target=wasm32-unknown-unknown
(without cargo-web), I get a WASM module that I can import without error.