commit f6e86e9a5e2b3a964e777495238bced8cb2126e8
parent c2821adfbab154bfd4eb3a4bd8bed2c0d6d50ff7
Author: André Bargull <andre.bargull@gmail.com>
Date: Thu, 23 Oct 2025 09:56:06 +0000
Bug 1995488 - Part 1: Avoid comparison against non-zero in clampIntToUint8 for riscv64. r=spidermonkey-reviewers,iain
`ClampIToUint8` was compiled to:
```asm
slti t4, t0, 0
li t5, 1
bne t4, t5, 0 -> skip
mv t0, zero
j 0 -> skip2
li t5, 255
bge t5, t0, 0 -> skip2
li t0, 255
```
Loading the immediate `1` into `t5` is unnecessary when instead comparing
against zero. But we can go even further and use the same approach as used
in `MacroAssemblerRiscv64Compat::minMax32` to check for negative values. That
saves another branch and `ClampIToUint8` is now compiled to:
```asm
sgtz t4, t0
neg t4, t4
and t0, t0, t4
li t4, 255
bge t4, t0, 0 -> skip
li t0, 255
```
Differential Revision: https://phabricator.services.mozilla.com/D269350
Diffstat:
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h b/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h
@@ -1324,18 +1324,23 @@ void MacroAssembler::byteSwap64(Register64 src) {
}
void MacroAssembler::clampIntToUint8(Register reg) {
// If reg is < 0, then we want to clamp to 0.
- Label skip, skip2;
- UseScratchRegisterScope temps(this);
- Register scratch = temps.Acquire();
- slti(scratch, reg, 0);
- ma_branch(&skip, NotEqual, scratch, Operand(1));
- ma_li(reg, Imm32(0));
- jump(&skip2);
- bind(&skip);
+ {
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+
+ // reg = -(reg > 0 ? 1 : 0) & reg
+ sgtz(scratch, reg);
+ neg(scratch, scratch);
+ and_(reg, reg, scratch);
+ }
+
// If reg is >= 255, then we want to clamp to 255.
- ma_branch(&skip2, LessThanOrEqual, reg, Operand(255));
- ma_li(reg, Imm32(255));
- bind(&skip2);
+ Label skip;
+ ma_branch(&skip, LessThanOrEqual, reg, Operand(255));
+ {
+ ma_li(reg, Imm32(255));
+ }
+ bind(&skip);
}
void MacroAssembler::clz32(Register src, Register dest, bool knownNotZero) {