""
   "%.\\tmul.wide.u32\\t%0, %1, %2;")
 
+(define_insn "smulhi3_highpart"
+  [(set (match_operand:HI 0 "nvptx_register_operand" "=R")
+       (truncate:HI
+        (lshiftrt:SI
+         (mult:SI (sign_extend:SI
+                   (match_operand:HI 1 "nvptx_register_operand" "R"))
+                  (sign_extend:SI
+                   (match_operand:HI 2 "nvptx_register_operand" "R")))
+         (const_int 16))))]
+  ""
+  "%.\\tmul.hi.s16\\t%0, %1, %2;")
+
+(define_insn "smulsi3_highpart"
+  [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
+       (truncate:SI
+        (lshiftrt:DI
+         (mult:DI (sign_extend:DI
+                   (match_operand:SI 1 "nvptx_register_operand" "R"))
+                  (sign_extend:DI
+                   (match_operand:SI 2 "nvptx_register_operand" "R")))
+         (const_int 32))))]
+  ""
+  "%.\\tmul.hi.s32\\t%0, %1, %2;")
+
+(define_insn "umulhi3_highpart"
+  [(set (match_operand:HI 0 "nvptx_register_operand" "=R")
+       (truncate:HI
+        (lshiftrt:SI
+         (mult:SI (zero_extend:SI
+                   (match_operand:HI 1 "nvptx_register_operand" "R"))
+                  (zero_extend:SI
+                   (match_operand:HI 2 "nvptx_register_operand" "R")))
+         (const_int 16))))]
+  ""
+  "%.\\tmul.hi.u16\\t%0, %1, %2;")
+
+(define_insn "umulsi3_highpart"
+  [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
+       (truncate:SI
+        (lshiftrt:DI
+         (mult:DI (zero_extend:DI
+                   (match_operand:SI 1 "nvptx_register_operand" "R"))
+                  (zero_extend:DI
+                   (match_operand:SI 2 "nvptx_register_operand" "R")))
+         (const_int 32))))]
+  ""
+  "%.\\tmul.hi.u32\\t%0, %1, %2;")
+
 ;; Shifts
 
 (define_insn "ashl<mode>3"
 
--- /dev/null
+/* { dg-do assemble } */
+/* { dg-options "-O2 -save-temps" } */
+
+short smulhi3_highpart(short x, short y)
+{
+  return ((int)x * (int)y) >> 16;
+}
+
+int smulsi3_highpart(int x, int y)
+{
+  return ((long)x * (long)y) >> 32;
+}
+
+/* { dg-final { scan-assembler-times "mul.hi.s16" 1 } } */
+/* { dg-final { scan-assembler-times "mul.hi.s32" 1 } } */
 
--- /dev/null
+/* { dg-do assemble } */
+/* { dg-options "-O2 -save-temps" } */
+
+unsigned short umulhi3_highpart(unsigned short x, unsigned short y)
+{
+  return ((unsigned int)x * (unsigned int)y) >> 16;
+}
+
+unsigned int umulsi3_highpart(unsigned int x, unsigned int y)
+{
+  return ((unsigned long)x * (unsigned long)y) >> 32;
+}
+
+/* { dg-final { scan-assembler-times "mul.hi.u16" 1 } } */
+/* { dg-final { scan-assembler-times "mul.hi.u32" 1 } } */