Index: llvm/lib/Target/Sparc/SparcISelLowering.cpp =================================================================== --- llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -2957,8 +2957,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 @@ -169,45 +169,46 @@ ; 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, %i5 -; SPARC64-NEXT: movcs %xcc, 1, %i5 -; SPARC64-NEXT: cmp %i4, 0 ; SPARC64-NEXT: mov %i3, %i4 -; SPARC64-NEXT: movne %xcc, 1, %i4 -; SPARC64-NEXT: cmp %l0, 0 +; SPARC64-NEXT: movcs %xcc, 1, %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: movne %xcc, 1, %i3 -; SPARC64-NEXT: and %i3, %i2, %i0 +; 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: or %i0, %i3, %i0 ; SPARC64-NEXT: or %i0, %i4, %i0 -; SPARC64-NEXT: or %i0, %i5, %i0 ; SPARC64-NEXT: srl %i0, 0, %i2 ; SPARC64-NEXT: mov %i1, %i0 ; SPARC64-NEXT: ret