https://gcc.gnu.org/g:d102db7194a3e30b9544724dd09b84de2fcfb0f7

commit r16-4949-gd102db7194a3e30b9544724dd09b84de2fcfb0f7
Author: Guo Jie <[email protected]>
Date:   Sat Nov 1 15:33:06 2025 +0800

    LoongArch: Correct the cost of mulh.{w[u]/d[u]}
    
    gcc/ChangeLog:
    
            * config/loongarch/loongarch.cc (loongarch_rtx_costs):
            Correct the cost of mulh.{w[u]|d[u]}.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/loongarch/mulh_wu.c: New test.

Diff:
---
 gcc/config/loongarch/loongarch.cc            | 27 ++++++++++++++++++++++++++-
 gcc/testsuite/gcc.target/loongarch/mulh_wu.c | 10 ++++++++++
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index c725d028d8c3..735753ad7e2d 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -3978,9 +3978,34 @@ loongarch_rtx_costs (rtx x, machine_mode mode, int 
outer_code,
                                      speed);
       return true;
 
+    case LSHIFTRT:
+      /* Correct the cost of mulh.{w[u]/d[u]}.  */
+      if (outer_code == TRUNCATE && CONST_INT_P (XEXP (x, 1))
+         && INTVAL (XEXP (x, 1)) == (GET_MODE_BITSIZE (mode) / 2)
+         && GET_CODE (XEXP (x, 0)) == MULT
+         && ((GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND
+              && GET_CODE (XEXP (XEXP (x, 0), 1)) == ZERO_EXTEND)
+             || (GET_CODE (XEXP (XEXP (x, 0), 0)) == SIGN_EXTEND
+                 && GET_CODE (XEXP (XEXP (x, 0), 1)) == SIGN_EXTEND))
+         && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == REG
+         && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == REG)
+       {
+         if (GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SImode
+             && GET_MODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == SImode)
+           {
+             *total = loongarch_cost->int_mult_si;
+             return true;
+           }
+         if (GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == DImode
+             && GET_MODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == DImode)
+           {
+             *total = loongarch_cost->int_mult_di;
+             return true;
+           }
+       }
+      /* Fall through.  */
     case ASHIFT:
     case ASHIFTRT:
-    case LSHIFTRT:
     case ROTATE:
     case ROTATERT:
       if (CONSTANT_P (XEXP (x, 1)))
diff --git a/gcc/testsuite/gcc.target/loongarch/mulh_wu.c 
b/gcc/testsuite/gcc.target/loongarch/mulh_wu.c
new file mode 100644
index 000000000000..53fc518313c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/mulh_wu.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target { loongarch64*-*-* } } } */
+/* { dg-options "-O3 -mabi=lp64d" } */
+/* { dg-final { scan-assembler "\tmulh.wu" } } */
+/* { dg-final { scan-assembler-not "\tlu32i.d" } } */
+
+unsigned int
+test (unsigned int *a)
+{
+  return *a / 60;
+}

Reply via email to