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/smulo-128-legalisation-lowering.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/SPARC/smulo-128-legalisation-lowering.ll @@ -0,0 +1,78 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=sparc-unknown-linux-gnu | FileCheck %s --check-prefixes=SPARC +; RUN: llc < %s -mtriple=sparc64-unknown-linux-gnu | FileCheck %s --check-prefixes=SPARC64 + +define { i128, i8 } @muloti_test(i128 %l, i128 %r) unnamed_addr #0 { +; SPARC-LABEL: muloti_test: +; SPARC: .cfi_startproc +; SPARC-NEXT: ! %bb.0: ! %start +; SPARC-NEXT: save %sp, -112, %sp +; SPARC-NEXT: .cfi_def_cfa_register %fp +; SPARC-NEXT: .cfi_window_save +; SPARC-NEXT: .cfi_register %o7, %i7 +; SPARC-NEXT: ld [%fp+92], %g2 +; SPARC-NEXT: ld [%fp+96], %g3 +; SPARC-NEXT: st %g0, [%fp+-4] +; SPARC-NEXT: add %fp, -4, %g4 +; SPARC-NEXT: st %g4, [%sp+100] +; SPARC-NEXT: st %g3, [%sp+96] +; SPARC-NEXT: st %g2, [%sp+92] +; SPARC-NEXT: mov %i0, %o0 +; SPARC-NEXT: mov %i1, %o1 +; SPARC-NEXT: mov %i2, %o2 +; SPARC-NEXT: mov %i3, %o3 +; SPARC-NEXT: mov %i4, %o4 +; SPARC-NEXT: call __muloti4 +; SPARC-NEXT: mov %i5, %o5 +; SPARC-NEXT: ld [%fp+-4], %i0 +; SPARC-NEXT: cmp %i0, 0 +; SPARC-NEXT: mov %o0, %i0 +; SPARC-NEXT: mov %o1, %i1 +; SPARC-NEXT: mov %o2, %i2 +; SPARC-NEXT: bne .LBB0_1 +; SPARC-NEXT: mov %o3, %i3 +; SPARC-NEXT: ! %bb.2: ! %start +; SPARC-NEXT: ret +; SPARC-NEXT: restore %g0, %g0, %o4 +; SPARC-NEXT: .LBB0_1: +; SPARC-NEXT: ret +; SPARC-NEXT: restore %g0, 1, %o4 +; +; SPARC64-LABEL: muloti_test: +; SPARC64: .cfi_startproc +; SPARC64-NEXT: ! %bb.0: ! %start +; SPARC64-NEXT: save %sp, -192, %sp +; SPARC64-NEXT: .cfi_def_cfa_register %fp +; SPARC64-NEXT: .cfi_window_save +; SPARC64-NEXT: .cfi_register %o7, %i7 +; SPARC64-NEXT: stx %g0, [%fp+2039] +; SPARC64-NEXT: add %fp, 2039, %o4 +; SPARC64-NEXT: mov %i0, %o0 +; SPARC64-NEXT: mov %i1, %o1 +; SPARC64-NEXT: mov %i2, %o2 +; SPARC64-NEXT: call __muloti4 +; SPARC64-NEXT: mov %i3, %o3 +; SPARC64-NEXT: ldx [%fp+2039], %i0 +; SPARC64-NEXT: mov %g0, %i1 +; SPARC64-NEXT: cmp %i0, 0 +; SPARC64-NEXT: movne %xcc, 1, %i1 +; SPARC64-NEXT: srl %i1, 0, %i2 +; SPARC64-NEXT: mov %o0, %i0 +; SPARC64-NEXT: ret +; SPARC64-NEXT: restore %g0, %o1, %o1 +start: + %0 = tail call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %l, i128 %r) #2 + %1 = extractvalue { i128, i1 } %0, 0 + %2 = extractvalue { i128, i1 } %0, 1 + %3 = zext i1 %2 to i8 + %4 = insertvalue { i128, i8 } undef, i128 %1, 0 + %5 = insertvalue { i128, i8 } %4, i8 %3, 1 + ret { i128, i8 } %5 +} + +; Function Attrs: nounwind readnone speculatable +declare { i128, i1 } @llvm.smul.with.overflow.i128(i128, i128) #1 + +attributes #0 = { nounwind readnone uwtable } +attributes #1 = { nounwind readnone speculatable } +attributes #2 = { nounwind } 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