Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8311764 | 17.0.9 | Fei Yang | P4 | Resolved | Fixed | b01 |
Currently, risc-v port converts floating point to integer using `FCVT_SAFE` in macroAssembler_riscv.cpp.
The main issue here is Java spec returns 0 when the floating point number is NaN [1].
But for RISC-V ISA, instructions converting a floating-point value to an integer value (`FCVT.W.S`/`FCVT.L.S`/`FCVT.W.D`/`FCVT.L.D`) return the largest/smallest value when the floating point number is NaN [2].
That requires additional logic to handle the case when the src of conversion is NaN, as the following code did:
```
#define FCVT_SAFE(FLOATCVT, FLOATEQ) \
void MacroAssembler:: FLOATCVT##_safe(Register dst, FloatRegister src, Register tmp) { \
Label L_Okay; \
fscsr(zr); \
FLOATCVT(dst, src); \
frcsr(tmp); \
andi(tmp, tmp, 0x1E); \
beqz(tmp, L_Okay); \
FLOATEQ(tmp, src, src); \
bnez(tmp, L_Okay); \
mv(dst, zr); \
bind(L_Okay); \
}
FCVT_SAFE(fcvt_w_s, feq_s)
FCVT_SAFE(fcvt_l_s, feq_s)
FCVT_SAFE(fcvt_w_d, feq_d)
FCVT_SAFE(fcvt_l_d, feq_d)
```
We can improve the logic of NaN checking with the `fclass` instruction just asJDK-8297359 did.
1. https://docs.oracle.com/javase/specs/jls/se20/html/jls-5.html#jls-5.1.3
2. https://github.com/riscv/riscv-isa-manual/blob/63aeaada9b2fee7ca15e5c6b6a28f3b710fb7e58/src/f-st-ext.adoc?plain=1#L365-L386
The main issue here is Java spec returns 0 when the floating point number is NaN [1].
But for RISC-V ISA, instructions converting a floating-point value to an integer value (`FCVT.W.S`/`FCVT.L.S`/`FCVT.W.D`/`FCVT.L.D`) return the largest/smallest value when the floating point number is NaN [2].
That requires additional logic to handle the case when the src of conversion is NaN, as the following code did:
```
#define FCVT_SAFE(FLOATCVT, FLOATEQ) \
void MacroAssembler:: FLOATCVT##_safe(Register dst, FloatRegister src, Register tmp) { \
Label L_Okay; \
fscsr(zr); \
FLOATCVT(dst, src); \
frcsr(tmp); \
andi(tmp, tmp, 0x1E); \
beqz(tmp, L_Okay); \
FLOATEQ(tmp, src, src); \
bnez(tmp, L_Okay); \
mv(dst, zr); \
bind(L_Okay); \
}
FCVT_SAFE(fcvt_w_s, feq_s)
FCVT_SAFE(fcvt_l_s, feq_s)
FCVT_SAFE(fcvt_w_d, feq_d)
FCVT_SAFE(fcvt_l_d, feq_d)
```
We can improve the logic of NaN checking with the `fclass` instruction just as
1. https://docs.oracle.com/javase/specs/jls/se20/html/jls-5.html#jls-5.1.3
2. https://github.com/riscv/riscv-isa-manual/blob/63aeaada9b2fee7ca15e5c6b6a28f3b710fb7e58/src/f-st-ext.adoc?plain=1#L365-L386
- backported by
-
JDK-8311764 RISC-V: Improve performance of floating point to integer conversion
- Resolved
- links to
-
Commit openjdk/jdk17u-dev/966fc82d
-
Commit openjdk/jdk/1f57ce0a
-
Commit openjdk/riscv-port-jdk17u/a9384466
-
Review openjdk/jdk17u-dev/1427
-
Review openjdk/jdk/13800
-
Review openjdk/riscv-port-jdk17u/57
(2 links to)