mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-21 05:50:55 +08:00
Emit 32-bit remainders of non-negative int32 operands
LLVM does not narrow the i64 urem of two extended int32s, so a proven non-negative int32 remainder by a constant took the 64-bit magic-number sequence (with its fixup). Emit urem i32 when both operands are proven int32 ranges.
This commit is contained in:
@@ -273,14 +273,17 @@ export function emitOperatorExpr(
|
||||
return uint32 === undefined ? number : { ...number, uint32 };
|
||||
}
|
||||
if (e.op === "%" && li.range.min >= 0 && ri.range.min > 0) {
|
||||
const range = { min: 0, max: Math.min(li.range.max, ri.range.max - 1) };
|
||||
if (withinInt32(li.range) && withinInt32(ri.range)) {
|
||||
// LLVM does not narrow the i64 remainder of two extended
|
||||
// int32s; a 32-bit one takes a shorter magic-number sequence.
|
||||
const result = B.tmp();
|
||||
B.line(`${result} = urem i32 ${narrowInteger(host, li)}, ${narrowInteger(host, ri)}`);
|
||||
return int32Number(host, result, range, e.type);
|
||||
}
|
||||
const result = B.tmp();
|
||||
B.line(`${result} = urem i64 ${left}, ${right}`);
|
||||
return integerNumber(
|
||||
host,
|
||||
result,
|
||||
{ min: 0, max: Math.min(li.range.max, ri.range.max - 1) },
|
||||
e.type,
|
||||
);
|
||||
return integerNumber(host, result, range, e.type);
|
||||
}
|
||||
if (e.op === "%") {
|
||||
const integer = emitSignedIntegerRemainder(host, l, li, ri);
|
||||
|
||||
Reference in New Issue
Block a user