llvm/llvm/test/CodeGen/SPARC/smulo-128-legalisation-lowering.ll

; 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) nounwind {
; SPARC-LABEL: muloti_test:
; SPARC:       ! %bb.0: ! %start
; SPARC-NEXT:    save %sp, -96, %sp
; SPARC-NEXT:    ld [%fp+96], %l1
; SPARC-NEXT:    mov %i3, %g4
; SPARC-NEXT:    mov %i2, %g2
; SPARC-NEXT:    umul %i3, %l1, %i3
; SPARC-NEXT:    rd %y, %i2
; SPARC-NEXT:    ld [%fp+92], %l2
; SPARC-NEXT:    umul %g2, %l1, %g3
; SPARC-NEXT:    rd %y, %l0
; SPARC-NEXT:    addcc %g3, %i2, %i2
; SPARC-NEXT:    addxcc %l0, 0, %g3
; SPARC-NEXT:    umul %g4, %l2, %l0
; SPARC-NEXT:    rd %y, %l3
; SPARC-NEXT:    addcc %l0, %i2, %i2
; SPARC-NEXT:    addxcc %l3, 0, %l0
; SPARC-NEXT:    addcc %g3, %l0, %g3
; SPARC-NEXT:    addxcc %g0, 0, %l0
; SPARC-NEXT:    umul %g2, %l2, %l3
; SPARC-NEXT:    rd %y, %l4
; SPARC-NEXT:    addcc %l3, %g3, %g3
; SPARC-NEXT:    umul %i1, %l1, %l3
; SPARC-NEXT:    rd %y, %l5
; SPARC-NEXT:    addxcc %l4, %l0, %l0
; SPARC-NEXT:    umul %i0, %l1, %l4
; SPARC-NEXT:    rd %y, %l6
; SPARC-NEXT:    addcc %l4, %l5, %l4
; SPARC-NEXT:    addxcc %l6, 0, %l5
; SPARC-NEXT:    umul %i1, %l2, %l6
; SPARC-NEXT:    rd %y, %l7
; SPARC-NEXT:    addcc %l6, %l4, %l4
; SPARC-NEXT:    addxcc %l7, 0, %l6
; SPARC-NEXT:    addcc %l5, %l6, %l5
; SPARC-NEXT:    addxcc %g0, 0, %l6
; SPARC-NEXT:    umul %i0, %l2, %l7
; SPARC-NEXT:    rd %y, %o0
; SPARC-NEXT:    addcc %l7, %l5, %l5
; SPARC-NEXT:    addxcc %o0, %l6, %l6
; SPARC-NEXT:    addcc %l3, %g3, %g3
; SPARC-NEXT:    addxcc %l4, %l0, %l0
; SPARC-NEXT:    addxcc %l5, 0, %l3
; SPARC-NEXT:    umul %g4, %i5, %l4
; SPARC-NEXT:    rd %y, %l5
; SPARC-NEXT:    addxcc %l6, 0, %l6
; SPARC-NEXT:    umul %g2, %i5, %l7
; SPARC-NEXT:    rd %y, %o0
; SPARC-NEXT:    addcc %l7, %l5, %l5
; SPARC-NEXT:    addxcc %o0, 0, %l7
; SPARC-NEXT:    umul %g4, %i4, %o0
; SPARC-NEXT:    rd %y, %o1
; SPARC-NEXT:    addcc %o0, %l5, %l5
; SPARC-NEXT:    addxcc %o1, 0, %o0
; SPARC-NEXT:    addcc %l7, %o0, %l7
; SPARC-NEXT:    addxcc %g0, 0, %o0
; SPARC-NEXT:    umul %g2, %i4, %o1
; SPARC-NEXT:    rd %y, %o2
; SPARC-NEXT:    addcc %o1, %l7, %l7
; SPARC-NEXT:    addxcc %o2, %o0, %o0
; SPARC-NEXT:    addcc %l4, %g3, %g3
; SPARC-NEXT:    addxcc %l5, %l0, %l0
; SPARC-NEXT:    addxcc %l7, 0, %l4
; SPARC-NEXT:    addxcc %o0, 0, %l5
; SPARC-NEXT:    addcc %l3, %l4, %l3
; SPARC-NEXT:    addxcc %l6, %l5, %l4
; SPARC-NEXT:    addxcc %g0, 0, %l5
; SPARC-NEXT:    umul %i1, %i5, %l6
; SPARC-NEXT:    rd %y, %l7
; SPARC-NEXT:    addxcc %g0, 0, %o0
; SPARC-NEXT:    umul %i0, %i5, %o1
; SPARC-NEXT:    rd %y, %o2
; SPARC-NEXT:    addcc %o1, %l7, %l7
; SPARC-NEXT:    addxcc %o2, 0, %o1
; SPARC-NEXT:    umul %i1, %i4, %o2
; SPARC-NEXT:    rd %y, %o3
; SPARC-NEXT:    addcc %o2, %l7, %l7
; SPARC-NEXT:    addxcc %o3, 0, %o2
; SPARC-NEXT:    addcc %o1, %o2, %o1
; SPARC-NEXT:    addxcc %g0, 0, %o2
; SPARC-NEXT:    umul %i0, %i4, %o3
; SPARC-NEXT:    rd %y, %o4
; SPARC-NEXT:    addcc %o3, %o1, %o1
; SPARC-NEXT:    addxcc %o4, %o2, %o2
; SPARC-NEXT:    addcc %l6, %l3, %l3
; SPARC-NEXT:    addxcc %l7, %l4, %l4
; SPARC-NEXT:    addxcc %o1, %l5, %l5
; SPARC-NEXT:    sra %i0, 31, %l6
; SPARC-NEXT:    smul %l6, %i4, %l7
; SPARC-NEXT:    umul %l6, %i5, %o1
; SPARC-NEXT:    rd %y, %o3
; SPARC-NEXT:    addxcc %o2, %o0, %i5
; SPARC-NEXT:    umul %l2, %l6, %l2
; SPARC-NEXT:    rd %y, %o0
; SPARC-NEXT:    add %o3, %l7, %l7
; SPARC-NEXT:    umul %l1, %l6, %l1
; SPARC-NEXT:    rd %y, %l6
; SPARC-NEXT:    add %l7, %o1, %l7
; SPARC-NEXT:    add %l6, %l2, %o2
; SPARC-NEXT:    add %o2, %l1, %o2
; SPARC-NEXT:    addcc %l1, %o1, %o1
; SPARC-NEXT:    addxcc %o2, %l7, %l7
; SPARC-NEXT:    addcc %l2, %l6, %o2
; SPARC-NEXT:    addxcc %o0, 0, %o3
; SPARC-NEXT:    addcc %l1, %o2, %o2
; SPARC-NEXT:    addxcc %l6, 0, %l6
; SPARC-NEXT:    addcc %o3, %l6, %l6
; SPARC-NEXT:    addxcc %g0, 0, %o3
; SPARC-NEXT:    addcc %l2, %l6, %l2
; SPARC-NEXT:    addxcc %o0, %o3, %l6
; SPARC-NEXT:    addcc %l2, %o1, %l2
; SPARC-NEXT:    sra %i4, 31, %i4
; SPARC-NEXT:    umul %g4, %i4, %g4
; SPARC-NEXT:    rd %y, %o0
; SPARC-NEXT:    addxcc %l6, %l7, %l6
; SPARC-NEXT:    umul %i4, %g2, %g2
; SPARC-NEXT:    rd %y, %l7
; SPARC-NEXT:    add %o0, %g4, %o1
; SPARC-NEXT:    smul %i0, %i4, %i0
; SPARC-NEXT:    umul %i1, %i4, %i1
; SPARC-NEXT:    rd %y, %i4
; SPARC-NEXT:    add %o1, %g2, %o1
; SPARC-NEXT:    add %i4, %i1, %i4
; SPARC-NEXT:    add %i4, %i0, %i0
; SPARC-NEXT:    addcc %i1, %g4, %i1
; SPARC-NEXT:    addxcc %i0, %o1, %i0
; SPARC-NEXT:    addcc %g4, %o0, %i4
; SPARC-NEXT:    addxcc %o0, 0, %o0
; SPARC-NEXT:    addcc %g2, %i4, %i4
; SPARC-NEXT:    addxcc %l7, 0, %o1
; SPARC-NEXT:    addcc %o0, %o1, %o0
; SPARC-NEXT:    addxcc %g0, 0, %o1
; SPARC-NEXT:    addcc %g2, %o0, %g2
; SPARC-NEXT:    addxcc %l7, %o1, %l7
; SPARC-NEXT:    addcc %g2, %i1, %i1
; SPARC-NEXT:    addxcc %l7, %i0, %i0
; SPARC-NEXT:    addcc %g4, %l1, %g2
; SPARC-NEXT:    addxcc %i4, %o2, %i4
; SPARC-NEXT:    addxcc %i1, %l2, %i1
; SPARC-NEXT:    addxcc %i0, %l6, %i0
; SPARC-NEXT:    addcc %l3, %g2, %g2
; SPARC-NEXT:    addxcc %l4, %i4, %i4
; SPARC-NEXT:    addxcc %l5, %i1, %i1
; SPARC-NEXT:    addxcc %i5, %i0, %i0
; SPARC-NEXT:    sra %l0, 31, %i5
; SPARC-NEXT:    xor %i0, %i5, %i0
; SPARC-NEXT:    xor %i4, %i5, %i4
; SPARC-NEXT:    or %i4, %i0, %i0
; SPARC-NEXT:    xor %i1, %i5, %i1
; SPARC-NEXT:    xor %g2, %i5, %i4
; SPARC-NEXT:    or %i4, %i1, %i1
; SPARC-NEXT:    or %i1, %i0, %i0
; SPARC-NEXT:    cmp %i0, 0
; SPARC-NEXT:    bne .LBB0_2
; SPARC-NEXT:    nop
; SPARC-NEXT:  ! %bb.1: ! %start
; SPARC-NEXT:    ba .LBB0_3
; SPARC-NEXT:    mov %g0, %i4
; SPARC-NEXT:  .LBB0_2:
; SPARC-NEXT:    mov 1, %i4
; SPARC-NEXT:  .LBB0_3: ! %start
; SPARC-NEXT:    mov %l0, %i0
; SPARC-NEXT:    ret
; SPARC-NEXT:    restore %g0, %g3, %o1
;
; SPARC64-LABEL: muloti_test:
; SPARC64:         .register %g2, #scratch
; SPARC64-NEXT:    .register %g3, #scratch
; SPARC64-NEXT:  ! %bb.0: ! %start
; SPARC64-NEXT:    save %sp, -176, %sp
; SPARC64-NEXT:    mov %i3, %i5
; SPARC64-NEXT:    mov %i2, %i3
; SPARC64-NEXT:    mov %i1, %i2
; SPARC64-NEXT:    mov %i0, %i4
; SPARC64-NEXT:    mov %g0, %o0
; SPARC64-NEXT:    mov %i1, %o1
; SPARC64-NEXT:    mov %g0, %o2
; SPARC64-NEXT:    call __multi3
; SPARC64-NEXT:    mov %i5, %o3
; SPARC64-NEXT:    mov %o0, %i0
; SPARC64-NEXT:    mov %o1, %i1
; SPARC64-NEXT:    mov %g0, %o0
; SPARC64-NEXT:    mov %i4, %o1
; SPARC64-NEXT:    mov %g0, %o2
; SPARC64-NEXT:    call __multi3
; SPARC64-NEXT:    mov %i5, %o3
; SPARC64-NEXT:    mov %g0, %g2
; SPARC64-NEXT:    add %o1, %i0, %i0
; SPARC64-NEXT:    cmp %i0, %o1
; SPARC64-NEXT:    movcs %xcc, 1, %g2
; SPARC64-NEXT:    srl %g2, 0, %g2
; SPARC64-NEXT:    add %o0, %g2, %l0
; SPARC64-NEXT:    mov %g0, %o0
; SPARC64-NEXT:    mov %i2, %o1
; SPARC64-NEXT:    mov %g0, %o2
; SPARC64-NEXT:    call __multi3
; SPARC64-NEXT:    mov %i3, %o3
; SPARC64-NEXT:    mov %g0, %g2
; SPARC64-NEXT:    mov %g0, %g3
; SPARC64-NEXT:    add %o1, %i0, %i0
; SPARC64-NEXT:    cmp %i0, %o1
; SPARC64-NEXT:    movcs %xcc, 1, %g2
; SPARC64-NEXT:    srl %g2, 0, %g2
; SPARC64-NEXT:    add %o0, %g2, %g2
; SPARC64-NEXT:    add %l0, %g2, %l1
; SPARC64-NEXT:    cmp %l1, %l0
; SPARC64-NEXT:    movcs %xcc, 1, %g3
; SPARC64-NEXT:    srl %g3, 0, %l0
; SPARC64-NEXT:    mov %g0, %o0
; SPARC64-NEXT:    mov %i4, %o1
; SPARC64-NEXT:    mov %g0, %o2
; SPARC64-NEXT:    call __multi3
; SPARC64-NEXT:    mov %i3, %o3
; SPARC64-NEXT:    mov %g0, %g2
; SPARC64-NEXT:    add %o0, %l0, %g3
; SPARC64-NEXT:    add %o1, %l1, %l1
; SPARC64-NEXT:    cmp %l1, %o1
; SPARC64-NEXT:    movcs %xcc, 1, %g2
; SPARC64-NEXT:    srl %g2, 0, %g2
; SPARC64-NEXT:    add %g3, %g2, %l2
; SPARC64-NEXT:    srax %i4, 63, %o2
; SPARC64-NEXT:    mov %i3, %o0
; SPARC64-NEXT:    mov %i5, %o1
; SPARC64-NEXT:    call __multi3
; SPARC64-NEXT:    mov %o2, %o3
; SPARC64-NEXT:    mov %o0, %i5
; SPARC64-NEXT:    mov %o1, %l0
; SPARC64-NEXT:    srax %i3, 63, %o0
; SPARC64-NEXT:    mov %o0, %o1
; SPARC64-NEXT:    mov %i4, %o2
; SPARC64-NEXT:    call __multi3
; SPARC64-NEXT:    mov %i2, %o3
; SPARC64-NEXT:    mov %g0, %i2
; SPARC64-NEXT:    mov %g0, %i3
; SPARC64-NEXT:    mov %g0, %i4
; SPARC64-NEXT:    add %o0, %i5, %i5
; SPARC64-NEXT:    add %o1, %l0, %g2
; SPARC64-NEXT:    cmp %g2, %o1
; SPARC64-NEXT:    movcs %xcc, 1, %i2
; SPARC64-NEXT:    srl %i2, 0, %i2
; SPARC64-NEXT:    add %i5, %i2, %i2
; SPARC64-NEXT:    add %l2, %i2, %i2
; SPARC64-NEXT:    add %l1, %g2, %i5
; SPARC64-NEXT:    cmp %i5, %l1
; SPARC64-NEXT:    movcs %xcc, 1, %i3
; SPARC64-NEXT:    srl %i3, 0, %i3
; SPARC64-NEXT:    add %i2, %i3, %i2
; SPARC64-NEXT:    srax %i0, 63, %i3
; SPARC64-NEXT:    xor %i2, %i3, %i2
; SPARC64-NEXT:    xor %i5, %i3, %i3
; SPARC64-NEXT:    or %i3, %i2, %i2
; SPARC64-NEXT:    movrnz %i2, 1, %i4
; SPARC64-NEXT:    srl %i4, 0, %i2
; SPARC64-NEXT:    ret
; SPARC64-NEXT:    restore
start:
  %0 = tail call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %l, i128 %r)
  %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
}

declare { i128, i1 } @llvm.smul.with.overflow.i128(i128, i128)