blob: a0ea014ed7638ad4a934867d3be57ba6b9403dbe (
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
|
From: Daniel Golle <daniel@makrotopia.org>
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>
---
--- 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)
{
|