Index: llvm/lib/Target/Sparc/SparcISelLowering.cpp
===================================================================
--- llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -2954,8 +2954,15 @@
   SDValue ShiftAmt = DAG.getConstant(63, dl, VT);
 
   SDValue RHS = Op.getOperand(1);
-  SDValue HiLHS = DAG.getNode(ISD::SRA, dl, VT, LHS, ShiftAmt);
-  SDValue HiRHS = DAG.getNode(ISD::SRA, dl, MVT::i64, RHS, ShiftAmt);
+  SDValue HiLHS, HiRHS;
+  if(isSigned) {
+    HiLHS = DAG.getNode(ISD::SRA, dl, VT, LHS, ShiftAmt);
+    HiRHS = DAG.getNode(ISD::SRA, dl, MVT::i64, RHS, ShiftAmt);
+  } else {
+    HiLHS = DAG.getConstant(0, dl, VT);
+    HiRHS = DAG.getConstant(0, dl, MVT::i64);
+  }
+
   SDValue Args[] = { HiLHS, LHS, HiRHS, RHS };
 
   TargetLowering::MakeLibCallOptions CallOptions;
Index: llvm/test/CodeGen/SPARC/64cond.ll
===================================================================
--- llvm/test/CodeGen/SPARC/64cond.ll
+++ llvm/test/CodeGen/SPARC/64cond.ll
@@ -112,9 +112,9 @@
 }
 
 ; CHECK-LABEL: setcc_resultty
-; CHECK-DAG:       srax %i0, 63, %o0
+; CHECK-DAG:       mov 0, %o0
 ; CHECK-DAG:       mov %i0, %o1
-; CHECK-DAG:       mov 0, %o2
+; CHECK-DAG:       mov %o0, %o2
 ; CHECK-DAG:       mov 32, %o3
 ; CHECK-DAG:       call __multi3
 ; CHECK:       cmp
Index: llvm/test/CodeGen/SPARC/mulo-64-lowering.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/SPARC/mulo-64-lowering.ll
@@ -0,0 +1,36 @@
+; RUN: llc -march=sparcv9 < %s | FileCheck %s
+
+declare { i64, i1 } @llvm.smul.with.overflow.i64(i64, i64)
+declare { i64, i1 } @llvm.umul.with.overflow.i64(i64, i64)
+
+; CHECK-LABEL: s:
+; CHECK: save %sp, -176, %sp
+; CHECK: srax %i0, 63, %o0
+; CHECK: srax %i1, 63, %o2
+; CHECK: mov     %i0, %o1
+; CHECK: call __multi3
+; CHECK: mov     %i1, %o3
+; CHECK: ret
+; CHECK-NEXT: restore %g0, %o1, %o0
+
+define i64 @s(i64 %0, i64 %1) {
+  %3 = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %0, i64 %1)
+  %4 = extractvalue { i64, i1 } %3, 0
+  ret i64 %4
+}
+
+; CHECK-label: u:
+; CHECK: save %sp, -176, %sp
+; CHECK: mov     0, %o0
+; CHECK: mov     %i0, %o1
+; CHECK: mov     %o0, %o2
+; CHECK: call __multi3
+; CHECK: mov     %i1, %o3
+; CHECK: ret
+; CHECK-NEXT: restore %g0, %o1, %o0
+
+define i64 @u(i64 %0, i64 %1) local_unnamed_addr #0 {
+  %3 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %0, i64 %1)
+  %4 = extractvalue { i64, i1 } %3, 0
+  ret i64 %4
+}
Index: llvm/test/CodeGen/SPARC/umulo-128-legalisation-lowering.ll
===================================================================
--- llvm/test/CodeGen/SPARC/umulo-128-legalisation-lowering.ll
+++ llvm/test/CodeGen/SPARC/umulo-128-legalisation-lowering.ll
@@ -196,47 +196,48 @@
 ; SPARC64-NEXT:    .cfi_def_cfa_register %fp
 ; SPARC64-NEXT:    .cfi_window_save
 ; SPARC64-NEXT:    .cfi_register %o7, %i7
-; SPARC64-NEXT:    srax %i2, 63, %o0
-; SPARC64-NEXT:    srax %i1, 63, %o2
+; SPARC64-NEXT:    mov 0, %i4
+; SPARC64-NEXT:    mov %i4, %o0
 ; SPARC64-NEXT:    mov %i2, %o1
+; SPARC64-NEXT:    mov %i4, %o2
 ; SPARC64-NEXT:    call __multi3
 ; SPARC64-NEXT:    mov %i1, %o3
-; SPARC64-NEXT:    mov %o0, %i4
-; SPARC64-NEXT:    mov %o1, %i5
-; SPARC64-NEXT:    srax %i0, 63, %o0
-; SPARC64-NEXT:    srax %i3, 63, %o2
+; SPARC64-NEXT:    mov %o0, %i5
+; SPARC64-NEXT:    mov %o1, %l0
+; SPARC64-NEXT:    mov %i4, %o0
 ; SPARC64-NEXT:    mov %i0, %o1
+; SPARC64-NEXT:    mov %i4, %o2
 ; SPARC64-NEXT:    call __multi3
 ; SPARC64-NEXT:    mov %i3, %o3
-; SPARC64-NEXT:    mov %o0, %l0
-; SPARC64-NEXT:    add %o1, %i5, %i5
-; SPARC64-NEXT:    mov 0, %o0
+; SPARC64-NEXT:    mov %o0, %l1
+; SPARC64-NEXT:    add %o1, %l0, %l0
+; SPARC64-NEXT:    mov %i4, %o0
 ; SPARC64-NEXT:    mov %i1, %o1
-; SPARC64-NEXT:    mov %o0, %o2
+; SPARC64-NEXT:    mov %i4, %o2
 ; SPARC64-NEXT:    call __multi3
 ; SPARC64-NEXT:    mov %i3, %o3
-; SPARC64-NEXT:    add %o0, %i5, %i1
+; SPARC64-NEXT:    add %o0, %l0, %i1
 ; SPARC64-NEXT:    mov %g0, %i3
 ; SPARC64-NEXT:    cmp %i1, %o0
-; SPARC64-NEXT:    mov %i3, %g2
-; SPARC64-NEXT:    movcs %xcc, 1, %g2
-; SPARC64-NEXT:    cmp %i5, 0
-; SPARC64-NEXT:    move %xcc, 0, %g2
-; SPARC64-NEXT:    cmp %i4, 0
 ; SPARC64-NEXT:    mov %i3, %i4
-; SPARC64-NEXT:    movne %xcc, 1, %i4
+; SPARC64-NEXT:    movcs %xcc, 1, %i4
 ; SPARC64-NEXT:    cmp %l0, 0
-; SPARC64-NEXT:    mov %i3, %i5
-; SPARC64-NEXT:    movne %xcc, 1, %i5
+; SPARC64-NEXT:    move %xcc, 0, %i4
+; SPARC64-NEXT:    cmp %l1, 0
+; SPARC64-NEXT:    mov %i3, %g2
+; SPARC64-NEXT:    movne %xcc, 1, %g2
 ; SPARC64-NEXT:    cmp %i2, 0
 ; SPARC64-NEXT:    mov %i3, %i2
 ; SPARC64-NEXT:    movne %xcc, 1, %i2
 ; SPARC64-NEXT:    cmp %i0, 0
+; SPARC64-NEXT:    mov %i3, %i0
+; SPARC64-NEXT:    movne %xcc, 1, %i0
+; SPARC64-NEXT:    and %i0, %i2, %i0
+; SPARC64-NEXT:    or %i0, %g2, %i0
+; SPARC64-NEXT:    cmp %i5, 0
 ; SPARC64-NEXT:    movne %xcc, 1, %i3
-; SPARC64-NEXT:    and %i3, %i2, %i0
-; SPARC64-NEXT:    or %i0, %i5, %i0
+; SPARC64-NEXT:    or %i0, %i3, %i0
 ; SPARC64-NEXT:    or %i0, %i4, %i0
-; SPARC64-NEXT:    or %i0, %g2, %i0
 ; SPARC64-NEXT:    srl %i0, 0, %i2
 ; SPARC64-NEXT:    mov %i1, %i0
 ; SPARC64-NEXT:    ret