diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a2730a90ca8b..99e1e4b3d8d2 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -4677,8 +4677,26 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
 	  return true;
 	}
       gcc_fallthrough ();
-    case ASHIFTRT:
     case LSHIFTRT:
+      /* mulh[u] pattern */
+      if (GET_CODE (x) == LSHIFTRT
+	  && TARGET_MUL
+	  && mode == GET_MODE_2XWIDER_MODE (word_mode).require ()
+	  && outer_code == TRUNCATE
+	  && (GET_CODE (XEXP (x, 0)) == MULT)
+	     && (GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND
+		 || GET_CODE (XEXP (XEXP (x, 0), 0)) == SIGN_EXTEND)
+	     && (GET_CODE (XEXP (XEXP (x, 0), 1)) == ZERO_EXTEND
+		 || GET_CODE (XEXP (XEXP (x, 0), 1)) == SIGN_EXTEND)
+	  && (GET_CODE (XEXP (x, 1)) == CONST_INT
+	      && INTVAL (XEXP (x, 1)) == BITS_PER_WORD))
+	{
+	  *total = COSTS_N_INSNS (tune_param->int_mul[mode == TImode]);
+	  return true;
+	}
+	/* Fall through.  */
+
+    case ASHIFTRT:
       *total = riscv_binary_cost (x, SINGLE_SHIFT_COST,
 				  CONSTANT_P (XEXP (x, 1)) ? 4 : 9);
       return false;
diff --git a/gcc/testsuite/gcc.target/riscv/pr125387.c b/gcc/testsuite/gcc.target/riscv/pr125387.c
new file mode 100644
index 000000000000..c381b7a28e21
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr125387.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target rv64} } */
+/* { dg-additional-options "-mtune=tt-ascalon-d8 -march=rv64gc" } 
+/* { dg-skip-if "" { *-*-* } { "-Os" "-Oz" } } */
+
+long foo1 (long x) { return x / 10000L; }
+long foo2 (long x) { return x / 30; }
+
+/* { dg-final { scan-assembler-times "mulh" 2 } } */
+/* { dg-final { scan-assembler-not "\tdiv\t" } } */
