INT_MIN % -1 aborts with integer overflow, while the C++ reference TVM returns 0 (which is correct, x % -1 is 0 for every x).
MRE
Create a test vm/tests/repro_mod_intmin.rs:
use ton_assembler::compile_code_to_cell;
use ton_vm::executor::Engine;
use ton_vm::stack::{Stack, StackItem};
const INT_MIN: &str = "-115792089237316195423570985008687907853269984665640564039457584007913129639936"; // -2^256
#[test]
fn mod_int_min_by_neg_one() {
let code = compile_code_to_cell(&format!("PUSHINT {INT_MIN} PUSHINT -1 MOD")).unwrap();
let mut engine =
Engine::with_capabilities(0).setup(code, None, Some(Stack::new()), None, vec![]).unwrap();
let res = engine.execute();
println!("execute() = {res:?}");
assert!(res.is_ok(), "INT_MIN % -1 must not trap, got {:?}", res.err());
assert_eq!(engine.stack().get(0).unwrap(), &StackItem::int(0));
}
Command:
cd src
cargo test --release -p ton_vm --test repro_mod_intmin -- --nocapture
Results:
execute() = Err(integer overflow, code 4, , vm/src/executor/math.rs:621)
test mod_int_min_by_neg_one ................. FAILED # INT_MIN % -1 traps (WRONG, expected 0)
C++ TVM
Identical instructions on the C++ TVM (fift's inline assembler) return 0, no trap:
printf '"Asm.fif" include <{ -115792089237316195423570985008687907853269984665640564039457584007913129639936 PUSHINT -1 PUSHINT MOD }>c <s constant code code 1 runvmx .s\n' | FIFTPATH=$TON/crypto/fift/lib $TON/build/crypto/fift -i
0 0 # result 0, exit code 0
INT_MIN % -1aborts with integer overflow, while the C++ reference TVM returns0(which is correct,x % -1is0for everyx).MRE
Create a test
vm/tests/repro_mod_intmin.rs:Command:
Results:
C++ TVM
Identical instructions on the C++ TVM (fift's inline assembler) return
0, no trap: