0xPolygonMiden / compiler

Compiler from MidenIR to Miden Assembly

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`OpEmitter::assert_unsigned_int32` blows up for `u32` case if values have high(32nd) bit set

greenhat opened this issue · comments

Discovered in #173.

The Rust a >= b (both u32) translates into the following IR:

(block 0 (param v0 i32) (param v1 i32)
(let (v3 u32) (cast v0))
(let (v4 u32) (cast v1))
(let (v5 i1) (gte v3 v4))
(let (v6 i32) (cast v5))
(ret v6))

From which the following MASM is generated:

dup.0
push.2147483648
u32and
eq.2147483648
assertz
swap.1
dup.0
push.2147483648
u32and
eq.2147483648
assertz
u32gte

The assertz fails if a or b have high(32nd) bit set, which is a valid u32 value.

EDIT: Can be reproduced by the commented tests mentioning this issue in their comment.
After the fix, these tests should be enabled.

@bitwalker I hit it in #225. As a temporary workaround, I suggest we disable it and emit nothing when casting to u32.

Just to confirm a detail here: the bit being set is the 32nd bit? Or the 31st? 2^32 is not representable as a 32 bit integer, 2^32-1 is the maximum value that will fit in 32 bits.

From the get_inputs test the value under cast is 4294967280 which is a valid u32 value with the 32nd bit set. But we're expecting the 32nd bit to be zero for u32 at

self.is_const_flag_set_u32(SIGN_BIT);