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;
+}

Reply via email to