On 1/12/25 10:44 PM, Zhijin Zeng wrote:
Compared to the patch v2, I added Zfinx check and Zfh check. Please help to
review again.
Thanks,
Zhijin
From 9ddb402cebe868050ebc2f75e4d87238161411b4 Mon Sep 17 00:00:00 2001
From: Zhijin Zeng <zhijin.z...@spacemit.com>
Date: Sat, 11 Jan 2025 12:09:11 +0800
Subject: [PATCH] RISC-V: Fix mode compatibility between floating-point and
integer value
I find there are some unnecessary fmv instructions in glibc math exp,
and reduce exp function to the attached test case. The unnecessary
fmv instructions as follow:
```
fld fa4,16(a4)
fmadd.d fa2,fa2,fa0,fa5
fld fa0,56(a4)
fmv.x.d a5,fa2 *****
fld fa2,48(a4)
fmv.d.x fa1,a5 *****
andi a3,a5,127
addi a3,a3,15
fsub.d fa5,fa1,fa5
slli a3,a3,3
```
The data of fa2 and fa1 are the same, we should directly use fa2
rather than fa1 in following instructions and save one fmv instruction.
The `fmv.d.x a5,fa2` is correspond to pattern `(subreg:DI (reg/v:DF 143`.
In ira pass, virtual register r143 is assigned to GP_REGS, so its data
need be copied to FP_REGS before `fsub.d fa5,fa1,fa5` by reload pass,
and that's exactly the `fmv.d.x fa1,a5` instruction.
To fix this, we need to change the 4 functions.
1. FP_REGS can't be used for virtual register 143 in `(subreg:DI (reg/v:DF 143`.
I change riscv_hard_regno_mode_ok and riscv_can_change_mode_class to
support it. RISC-V fmv variant instructions can be used to move data
between FP_REGS and GR_REGS, and FP_REGS are compatible with DImode and
SImode.
2. The fwprop1 pass will fold the `(subreg:DI (reg/v:DF 143` and make
the cost calcutation method get incorrect cost and still assign r143 to
GP_REGS. Actually FP_REGS and GR_REGS are not tieable without Zfinx
extension, and need to fix riscv_modes_tieable_p.
3. JALR_REGS is also a subset of GR_REGS and need to be taken
into acount in riscv_register_move_cost, otherwise it will get
a incorrect cost.
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_register_move_cost):
(riscv_hard_regno_mode_ok):
(riscv_modes_tieable_p):
(riscv_can_change_mode_class):
gcc/testsuite/ChangeLog:
* gcc.target/riscv/fwprop1-modes-tieable.c: New test.
Given this is not a correctness issue, but a performance improvement, it
probably needs to defer to gcc-16.
jeff