]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
LoongArch: Improve TARGET_MODES_TIEABLE_P implementation
authorGuo Jie <guojie@loongson.cn>
Sun, 2 Nov 2025 03:32:44 +0000 (11:32 +0800)
committerLulu Cheng <chenglulu@loongson.cn>
Mon, 3 Nov 2025 08:10:58 +0000 (16:10 +0800)
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.

gcc/config/loongarch/loongarch.cc
gcc/config/loongarch/loongarch.md
gcc/testsuite/gcc.target/loongarch/mode-tieable-opt.c [new file with mode: 0644]

index 6dc2006003e76d2032099e6b5450dd9a13c2465d..d11fe496a015b2f9141303a07d83bbd6a70cb9c5 100644 (file)
@@ -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.  */
index c61abcea3eda11dc54214e74779c14d4ef33078d..2f4817d885c8fcb6676e8bcf5abf488edc2b86a6 100644 (file)
 })
 
 (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 (file)
index 0000000..d6a6577
--- /dev/null
@@ -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;
+}