Pushed to r16-5071.

在 2025/11/5 上午9:50, Lulu Cheng 写道:
This optimization can eliminate redundant immediate load instructions
during CSE optimization.

gcc/ChangeLog:

        * config/loongarch/loongarch.cc
        (loongarch_legitimize_move): Optimize.

gcc/testsuite/ChangeLog:

        * gcc.target/loongarch/sign-extend-6.c: New test.

---
  gcc/config/loongarch/loongarch.cc               | 15 ++++++++++++++-
  .../gcc.target/loongarch/sign-extend-6.c        | 17 +++++++++++++++++
  2 files changed, 31 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/gcc.target/loongarch/sign-extend-6.c

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index df5b570d917..462743f8399 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -3534,7 +3534,20 @@ loongarch_legitimize_move (machine_mode mode, rtx dest, 
rtx src)
  {
    if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode))
      {
-      loongarch_emit_move (dest, force_reg (mode, src));
+      /* When loading fixed-point scalar data, if the size of the mode
+        is smaller than the size of `word_mode`, the immediate value
+        is first loaded into a register of type `word_mode`.
+        This facilitates the elimination of common self-expressions.
+        This reduces redundant immediate value loading instructions.  */
+      rtx tmp;
+      if (GET_MODE_CLASS (mode) == MODE_INT
+         && GET_CODE (src) == CONST_INT
+         && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
+       tmp = gen_lowpart (mode, force_reg (word_mode, src));
+      else
+       tmp = force_reg (mode, src);
+
+      loongarch_emit_move (dest, tmp);
        return true;
      }
diff --git a/gcc/testsuite/gcc.target/loongarch/sign-extend-6.c b/gcc/testsuite/gcc.target/loongarch/sign-extend-6.c
new file mode 100644
index 00000000000..74d0e589b1e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/sign-extend-6.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=lp64d -O2" } */
+/* { dg-final { scan-assembler-times "addi.w\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,1\t" 
1 } } */
+
+extern unsigned short d;
+int
+test (int a, unsigned short b)
+{
+  if (a > 0)
+    {
+      d = 1;
+      if (b > d)
+       return 10;
+    }
+
+  return 50;
+}

Reply via email to