blob: 6e41aeaf79e7c2ff300ff298f8552be990c09eec (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
From 263d7aecb08f96a70a2004c6b1af906fd02f53ea Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Wed, 23 Sep 2026 14:33:27 +0100
Subject: [PATCH] JavaScriptCore: RISCV64: fix nonPreservedNonArgumentFPR0
aliasing argumentFPR1
On RISCV64, FPRInfo declared
nonPreservedNonArgumentFPR0 = RISCV64Registers::f11
but f11 is fa1 = argumentFPR1. BBQJIT pins wasmScratchFPR to
nonPreservedNonArgumentFPR0 and uses it to materialise f32/f64
immediates for binary float comparisons (emitCompareF32/F64). When the
non-immediate operand is bound to fa1 (e.g. wasm result/argument 1),
emitMoveConst into the "scratch" register silently overwrites that
value before the comparison runs.
Symptom: spec-tests/wasm/stress multi-return tests that compare each
returned f32/f64 against a constant fail at the fa1 slot:
wasm-wasm-call-many-return-types-on-stack-no-args.js
wasm-wasm-call-indirect-many-return-types-on-stack.js
wasm-js-call-many-return-types-on-stack-no-args.js
The bug is not about spill pressure; it is the scratch FPR aliasing an
argument/return FPR for any value bound to fa1.
Use f0 (ft0) -- a RISC-V caller-saved temporary outside the f10..f17
argument/return set -- matching the pattern used by ARM64 (q16) and
X86_64 (xmm8).
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
Source/JavaScriptCore/jit/FPRInfo.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/Source/JavaScriptCore/jit/FPRInfo.h
+++ b/Source/JavaScriptCore/jit/FPRInfo.h
@@ -366,7 +366,7 @@ public:
static constexpr FPRReg argumentFPR7 = RISCV64Registers::f17; // fpRegT7
static constexpr FPRReg returnValueFPR = RISCV64Registers::f10; // fpRegT0
- static constexpr FPRReg nonPreservedNonArgumentFPR0 = RISCV64Registers::f11;
+ static constexpr FPRReg nonPreservedNonArgumentFPR0 = RISCV64Registers::f0;
static FPRReg toRegister(unsigned index)
{
|