https://gcc.gnu.org/g:870fed53f5e7f18b1134737f007193ebff5ef2b7
commit r16-4954-g870fed53f5e7f18b1134737f007193ebff5ef2b7 Author: Guo Jie <[email protected]> Date: Sun Nov 2 11:32:44 2025 +0800 LoongArch: Improve TARGET_MODES_TIEABLE_P implementation Make scalar int mode and scalar fp mode tieable, so movgr2fr and movfr2gr can be used instead of memory access. For example, in pattern '*movsi_internal', when matching gr->fr, due to the constraint '*' in alt4, it will match alt5, resulting in memory access instead of movgr2fr. gcc/ChangeLog: * config/loongarch/loongarch.cc (loongarch_modes_tieable_p): Make MODE_FLOAT and MODE_INT tieable. * config/loongarch/loongarch.md: Adjust constraints. gcc/testsuite/ChangeLog: * gcc.target/loongarch/mode-tieable-opt.c: New test. Diff: --- gcc/config/loongarch/loongarch.cc | 6 +++++- gcc/config/loongarch/loongarch.md | 4 ++-- gcc/testsuite/gcc.target/loongarch/mode-tieable-opt.c | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 6dc2006003e7..d11fe496a015 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -7196,7 +7196,11 @@ loongarch_modes_tieable_p (machine_mode mode1, machine_mode mode2) prefer to put one of them in FPRs. */ return (mode1 == mode2 || (!loongarch_mode_ok_for_mov_fmt_p (mode1) - && !loongarch_mode_ok_for_mov_fmt_p (mode2))); + && !loongarch_mode_ok_for_mov_fmt_p (mode2)) + || (GET_MODE_CLASS(mode1) == MODE_FLOAT + && GET_MODE_CLASS(mode2) == MODE_INT) + || (GET_MODE_CLASS(mode2) == MODE_FLOAT + && GET_MODE_CLASS(mode1) == MODE_INT)); } /* Implement TARGET_PREFERRED_RELOAD_CLASS. */ diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index c61abcea3eda..2f4817d885c8 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -2339,8 +2339,8 @@ }) (define_insn_and_split "*movsi_internal" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,w,*f,f,*r,*m") - (match_operand:SI 1 "move_operand" "r,Yd,w,rJ,*r*J,m,*f,*f"))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,w,f,f,r,*m") + (match_operand:SI 1 "move_operand" "r,Yd,w,rJ,rJ,m,f,*f"))] "(register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode))" { return loongarch_output_move (operands); } diff --git a/gcc/testsuite/gcc.target/loongarch/mode-tieable-opt.c b/gcc/testsuite/gcc.target/loongarch/mode-tieable-opt.c new file mode 100644 index 000000000000..d6a6577bfe54 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/mode-tieable-opt.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target { loongarch64*-*-* } } } */ +/* { dg-options "-O3 -mno-lsx" } */ +/* { dg-final { scan-assembler-not "stptr\.d" } } */ +/* { dg-final { scan-assembler-not "fld\.d" } } */ +/* { dg-final { scan-assembler-not "fst\.d" } } */ +/* { dg-final { scan-assembler-not "ldptr\.d" } } */ +/* { dg-final { scan-assembler "movgr2fr\.d" } } */ +/* { dg-final { scan-assembler "movfr2gr\.d" } } */ + +typedef double vec __attribute__ ((vector_size(16))); + +vec +foo (vec x, double a) +{ + x[0] -= a; + return x; +}
