https://gcc.gnu.org/g:efc69e28d8c552a98f09a6c17cedaa189d7bce25
commit r17-3984-gefc69e28d8c552a98f09a6c17cedaa189d7bce25 Author: Takayuki 'January June' Suwa <[email protected]> Date: Mon Sep 7 23:04:13 2026 +0900 xtensa: Discourage use of hardware FP registers for SFmode load/store In the Xtensa ISA, using either address (general-purpose) registers or hardware floating-point registers for loading or storing single-precision floating-point values results in no difference in semantics or speed; however, the former is advantageous in terms of code size when the Code Density Option is configured. This patch lowers the priority of H/W FP registers for SFmode load/store operations by prefixing the register constraints with '*' in the alternative specifications within the MD insn definition. /* example */ extern float b; void test0(int a) { b = a ? b : 0; } void test1(int a) { b = a ? b : 1; } ;; before (-O2 ; TARGET_HARD_FLOAT | TARGET_DENSITY) .literal_position .literal .LC0, b test0: entry sp, 32 l32r a8, .LC0 beqz.n a2, .L3 lsi f0, a8, 0 ;; load to FPR j .L2 .L3: const.s f0, 0 ;; set +0.f to FPR .L2: ssi f0, a8, 0 ;; store from FPR retw.n .literal_position .literal .LC1, b test1: entry sp, 32 l32r a8, .LC1 beqz.n a2, .L7 lsi f0, a8, 0 ;; load to FPR j .L6 .L7: const.s f0, 1 ;; set 1.f to FPR .L6: ssi f0, a8, 0 ;; store from FPR retw.n ;; after (-O2 ; TARGET_HARD_FLOAT | TARGET_DENSITY) .literal_position .literal .LC0, b test0: entry sp, 32 l32r a8, .LC0 beqz.n a2, .L3 l32i.n a9, a8, 0 ;; load to GPR (1 byte shorter) j .L2 .L3: movi.n a9, 0 ;; set +0.f to GPR (1 byte shorter) .L2: s32i.n a9, a8, 0 ;; store from GPR (1 byte shorter) retw.n .literal_position .literal .LC1, b test1: entry sp, 32 l32r a8, .LC1 beqz.n a2, .L7 lsi f0, a8, 0 ;; load to FPR (no changes) j .L6 .L7: const.s f0, 1 ;; set 1.f to FPR (no changes) ;; Since this instruction constrains the ;; regclass, the lowered priority of FPR ;; is not taken into account. .L6: ssi f0, a8, 0 ;; store from FPR (no changes) retw.n gcc/ChangeLog: * config/xtensa/xtensa.md (movsf_internal): Prefix register constraints with '*' for hardware FP register load and store alternatives. Diff: --- gcc/config/xtensa/xtensa.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index d6ef0efd150e..753f23412be8 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -1411,23 +1411,23 @@ "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)" {@ [cons: =0, 1; attrs: type, length] - [D, Gz; move , 2] movi.n\t%0, 0 - [a, Gz; move , 3] movi\t%0, 0 - [f, Gc; farith, 3] const.s\t%0, %G1 - [W, iF; move , 6] const16\t%0, %t1\;const16\t%0, %b1 - [a, Y; load , 3] movi\t%0, %y1 - [a, T; load , 3] %v1l32r\t%0, %1 - [D, d; move , 2] mov.n\t%0, %1 - [a, r; move , 3] mov\t%0, %1 - [f, f; farith, 3] mov.s\t%0, %1 - [f, r; farith, 3] wfr\t%0, %1 - [a, f; farith, 3] rfr\t%0, %1 - [D, R; load , 2] %v1l32i.n\t%0, %1 - [a, U; load , 3] %v1l32i\t%0, %1 - [f, U; fload , 3] %v1lsi\t%0, %1 - [R, d; store , 2] %v0s32i.n\t%1, %0 - [U, r; store , 3] %v0s32i\t%1, %0 - [U, f; fstore, 3] %v0ssi\t%1, %0 + [ D, Gz; move , 2] movi.n\t%0, 0 + [ a, Gz; move , 3] movi\t%0, 0 + [ f, Gc; farith, 3] const.s\t%0, %G1 + [ W, iF; move , 6] const16\t%0, %t1\;const16\t%0, %b1 + [ a, Y; load , 3] movi\t%0, %y1 + [ a, T; load , 3] %v1l32r\t%0, %1 + [ D, d; move , 2] mov.n\t%0, %1 + [ a, r; move , 3] mov\t%0, %1 + [ f, f; farith, 3] mov.s\t%0, %1 + [ f, r; farith, 3] wfr\t%0, %1 + [ a, f; farith, 3] rfr\t%0, %1 + [ D, R; load , 2] %v1l32i.n\t%0, %1 + [ a, U; load , 3] %v1l32i\t%0, %1 + [*f, U; fload , 3] %v1lsi\t%0, %1 + [ R, d; store , 2] %v0s32i.n\t%1, %0 + [ U, r; store , 3] %v0s32i\t%1, %0 + [ U, *f; fstore, 3] %v0ssi\t%1, %0 } [(set_attr "mode" "SF")])
