Repro
const r = Math.imul(0x01000193, 0x811c9dc5);
console.log('imul result:', r);
Actual (Perry 0.5.30)
Error compiling module '…': lowering entry of module '…': lowering init
statements of module '…': perry-codegen Phase 2: expression MathImul not
yet supported
Expected
Compile successfully; print the 32-bit-wrap product (e.g. -2110866647).
Notes
Math.imul(a, b) is the canonical spelling for 32-bit-wrap multiplication in portable JS/TS — hash functions (FNV-1a-32, MurmurHash3, xxhash32, CityHash32), PRNGs (PCG, xorshift*), and most CRC32 implementations all use it. Without it, TS that targets Node and Perry has to branch, or hand-roll the 16-bit hi/lo split:
function imul32(a: number, b: number): number {
const aHi = (a >>> 16) & 0xffff, aLo = a & 0xffff;
const bHi = (b >>> 16) & 0xffff, bLo = b & 0xffff;
return ((aLo * bLo) + (((aHi * bLo + aLo * bHi) << 16) >>> 0)) | 0;
}
— which is what the honest_bench/workloads/3_image_convolution/perry/image_conv.ts and honest_bench/workloads/1_json_pipeline/perry/json_pipeline.ts files do as a workaround.
The underlying primitive should be cheap to lower: fptosi a → trunc to i32 → fptosi b → trunc to i32 → mul i32 → sitofp.
Repro
Actual (Perry 0.5.30)
Expected
Compile successfully; print the 32-bit-wrap product (e.g.
-2110866647).Notes
Math.imul(a, b)is the canonical spelling for 32-bit-wrap multiplication in portable JS/TS — hash functions (FNV-1a-32, MurmurHash3, xxhash32, CityHash32), PRNGs (PCG, xorshift*), and most CRC32 implementations all use it. Without it, TS that targets Node and Perry has to branch, or hand-roll the 16-bit hi/lo split:— which is what the
honest_bench/workloads/3_image_convolution/perry/image_conv.tsandhonest_bench/workloads/1_json_pipeline/perry/json_pipeline.tsfiles do as a workaround.The underlying primitive should be cheap to lower:
fptosi a → trunc to i32 → fptosi b → trunc to i32 → mul i32 → sitofp.