IR `cast` from i32 to u32 produces MASM that does not support full u32 range
greenhat opened this issue · comments
Denys Zadorozhnyi commented
Discovered in #49
Rust <=
(le) op on u32 values compiles to the following IR:
module noname
const $0 = 0x00100000;
global external @__stack_pointer : i32 = $0 { id = 0 };
global external @gv1 : i32 = $0 { id = 1 };
global external @gv2 : i32 = $0 { id = 2 };
pub fn entrypoint(i32, i32) -> i32 {
block0(v0: i32, v1: i32):
v3 = cast v0 : u32;
v4 = cast v1 : u32;
v5 = lt v3, v4 : i1;
v6 = cast v5 : i32;
br block1(v6);
block1(v2: i32):
ret v2;
}
Which then generates the following MASM:
export.entrypoint
dup.0
push.2147483648
u32.and
eq.2147483648
assertz
swap.1
dup.0
push.2147483648
u32.and
eq.2147483648
assertz
u32.lt.checked
end
begin
exec.entrypoint
end
Which fails on assert in VM in proptest with minimal example of (0, 2147483648).
EDIT: see commented test reproducing this issue in #49 in instructions.rs
(any comparison test for u32).
Denys Zadorozhnyi commented
Nevermind. I did not convert the op result(u64) to the expected type (u32).