; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; Test usage of VACC/VSCBI.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s --check-prefix=BASELINE
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s --check-prefix=Z13

define i128 @i128_subc_1(i128 %a, i128 %b) unnamed_addr {
; BASELINE-LABEL: i128_subc_1:
; BASELINE:       # %bb.0:
; BASELINE-NEXT:    stmg %r14, %r15, 112(%r15)
; BASELINE-NEXT:    .cfi_offset %r14, -48
; BASELINE-NEXT:    .cfi_offset %r15, -40
; BASELINE-NEXT:    lg %r5, 0(%r4)
; BASELINE-NEXT:    lg %r14, 0(%r3)
; BASELINE-NEXT:    lg %r1, 8(%r3)
; BASELINE-NEXT:    clgr %r14, %r5
; BASELINE-NEXT:    ipm %r0
; BASELINE-NEXT:    clg %r1, 8(%r4)
; BASELINE-NEXT:    ipm %r1
; BASELINE-NEXT:    cgrjlh %r14, %r5, .LBB0_2
; BASELINE-NEXT:  # %bb.1:
; BASELINE-NEXT:    xilf %r1, 4294967295
; BASELINE-NEXT:    risbg %r0, %r1, 63, 191, 36
; BASELINE-NEXT:    j .LBB0_3
; BASELINE-NEXT:  .LBB0_2:
; BASELINE-NEXT:    xilf %r0, 4294967295
; BASELINE-NEXT:    risbg %r0, %r0, 63, 191, 36
; BASELINE-NEXT:  .LBB0_3:
; BASELINE-NEXT:    llgfr %r0, %r0
; BASELINE-NEXT:    stg %r0, 8(%r2)
; BASELINE-NEXT:    mvghi 0(%r2), 0
; BASELINE-NEXT:    lmg %r14, %r15, 112(%r15)
; BASELINE-NEXT:    br %r14
;
; Z13-LABEL: i128_subc_1:
; Z13:       # %bb.0:
; Z13-NEXT:    vl %v0, 0(%r4), 3
; Z13-NEXT:    vl %v1, 0(%r3), 3
; Z13-NEXT:    vscbiq %v0, %v1, %v0
; Z13-NEXT:    vst %v0, 0(%r2), 3
; Z13-NEXT:    br %r14
  %cmp = icmp uge i128 %a, %b
  %ext = zext i1 %cmp to i128
  ret i128 %ext
}

define i128 @i128_subc_2(i128 %a, i128 %b) unnamed_addr {
; BASELINE-LABEL: i128_subc_2:
; BASELINE:       # %bb.0:
; BASELINE-NEXT:    stmg %r14, %r15, 112(%r15)
; BASELINE-NEXT:    .cfi_offset %r14, -48
; BASELINE-NEXT:    .cfi_offset %r15, -40
; BASELINE-NEXT:    lg %r5, 0(%r4)
; BASELINE-NEXT:    lg %r14, 0(%r3)
; BASELINE-NEXT:    lg %r0, 8(%r3)
; BASELINE-NEXT:    clgr %r14, %r5
; BASELINE-NEXT:    ipm %r1
; BASELINE-NEXT:    clg %r0, 8(%r4)
; BASELINE-NEXT:    ipm %r0
; BASELINE-NEXT:    cgrjlh %r14, %r5, .LBB1_2
; BASELINE-NEXT:  # %bb.1:
; BASELINE-NEXT:    afi %r0, -536870912
; BASELINE-NEXT:    srl %r0, 31
; BASELINE-NEXT:    j .LBB1_3
; BASELINE-NEXT:  .LBB1_2:
; BASELINE-NEXT:    afi %r1, -536870912
; BASELINE-NEXT:    srl %r1, 31
; BASELINE-NEXT:    lr %r0, %r1
; BASELINE-NEXT:  .LBB1_3:
; BASELINE-NEXT:    llgfr %r0, %r0
; BASELINE-NEXT:    stg %r0, 8(%r2)
; BASELINE-NEXT:    mvghi 0(%r2), 0
; BASELINE-NEXT:    lmg %r14, %r15, 112(%r15)
; BASELINE-NEXT:    br %r14
;
; Z13-LABEL: i128_subc_2:
; Z13:       # %bb.0:
; Z13-NEXT:    vl %v0, 0(%r3), 3
; Z13-NEXT:    vl %v1, 0(%r4), 3
; Z13-NEXT:    vscbiq %v0, %v1, %v0
; Z13-NEXT:    vst %v0, 0(%r2), 3
; Z13-NEXT:    br %r14
  %cmp = icmp ule i128 %a, %b
  %ext = zext i1 %cmp to i128
  ret i128 %ext
}

define i128 @i128_addc_1(i128 %a, i128 %b) {
; BASELINE-LABEL: i128_addc_1:
; BASELINE:       # %bb.0:
; BASELINE-NEXT:    lg %r0, 8(%r3)
; BASELINE-NEXT:    lg %r1, 0(%r3)
; BASELINE-NEXT:    alg %r0, 8(%r4)
; BASELINE-NEXT:    alcg %r1, 0(%r4)
; BASELINE-NEXT:    ipm %r0
; BASELINE-NEXT:    risbg %r0, %r0, 63, 191, 35
; BASELINE-NEXT:    stg %r0, 8(%r2)
; BASELINE-NEXT:    mvghi 0(%r2), 0
; BASELINE-NEXT:    br %r14
;
; Z13-LABEL: i128_addc_1:
; Z13:       # %bb.0:
; Z13-NEXT:    vl %v0, 0(%r4), 3
; Z13-NEXT:    vl %v1, 0(%r3), 3
; Z13-NEXT:    vaccq %v0, %v1, %v0
; Z13-NEXT:    vst %v0, 0(%r2), 3
; Z13-NEXT:    br %r14
  %sum = add i128 %a, %b
  %cmp = icmp ult i128 %sum, %a
  %ext = zext i1 %cmp to i128
  ret i128 %ext
}

define i128 @i128_addc_2(i128 %a, i128 %b) {
; BASELINE-LABEL: i128_addc_2:
; BASELINE:       # %bb.0:
; BASELINE-NEXT:    lg %r0, 8(%r3)
; BASELINE-NEXT:    lg %r1, 0(%r3)
; BASELINE-NEXT:    alg %r0, 8(%r4)
; BASELINE-NEXT:    alcg %r1, 0(%r4)
; BASELINE-NEXT:    ipm %r0
; BASELINE-NEXT:    risbg %r0, %r0, 63, 191, 35
; BASELINE-NEXT:    stg %r0, 8(%r2)
; BASELINE-NEXT:    mvghi 0(%r2), 0
; BASELINE-NEXT:    br %r14
;
; Z13-LABEL: i128_addc_2:
; Z13:       # %bb.0:
; Z13-NEXT:    vl %v0, 0(%r4), 3
; Z13-NEXT:    vl %v1, 0(%r3), 3
; Z13-NEXT:    vaccq %v0, %v1, %v0
; Z13-NEXT:    vst %v0, 0(%r2), 3
; Z13-NEXT:    br %r14
  %sum = add i128 %a, %b
  %cmp = icmp ult i128 %sum, %b
  %ext = zext i1 %cmp to i128
  ret i128 %ext
}

define i128 @i128_addc_3(i128 %a, i128 %b) {
; BASELINE-LABEL: i128_addc_3:
; BASELINE:       # %bb.0:
; BASELINE-NEXT:    lg %r0, 8(%r3)
; BASELINE-NEXT:    lg %r1, 0(%r3)
; BASELINE-NEXT:    alg %r0, 8(%r4)
; BASELINE-NEXT:    alcg %r1, 0(%r4)
; BASELINE-NEXT:    ipm %r0
; BASELINE-NEXT:    risbg %r0, %r0, 63, 191, 35
; BASELINE-NEXT:    stg %r0, 8(%r2)
; BASELINE-NEXT:    mvghi 0(%r2), 0
; BASELINE-NEXT:    br %r14
;
; Z13-LABEL: i128_addc_3:
; Z13:       # %bb.0:
; Z13-NEXT:    vl %v0, 0(%r4), 3
; Z13-NEXT:    vl %v1, 0(%r3), 3
; Z13-NEXT:    vaccq %v0, %v1, %v0
; Z13-NEXT:    vst %v0, 0(%r2), 3
; Z13-NEXT:    br %r14
  %sum = add i128 %a, %b
  %cmp = icmp ugt i128 %a, %sum
  %ext = zext i1 %cmp to i128
  ret i128 %ext
}

define i128 @i128_addc_4(i128 %a, i128 %b) {
; BASELINE-LABEL: i128_addc_4:
; BASELINE:       # %bb.0:
; BASELINE-NEXT:    lg %r0, 8(%r3)
; BASELINE-NEXT:    lg %r1, 0(%r3)
; BASELINE-NEXT:    alg %r0, 8(%r4)
; BASELINE-NEXT:    alcg %r1, 0(%r4)
; BASELINE-NEXT:    ipm %r0
; BASELINE-NEXT:    risbg %r0, %r0, 63, 191, 35
; BASELINE-NEXT:    stg %r0, 8(%r2)
; BASELINE-NEXT:    mvghi 0(%r2), 0
; BASELINE-NEXT:    br %r14
;
; Z13-LABEL: i128_addc_4:
; Z13:       # %bb.0:
; Z13-NEXT:    vl %v0, 0(%r4), 3
; Z13-NEXT:    vl %v1, 0(%r3), 3
; Z13-NEXT:    vaccq %v0, %v1, %v0
; Z13-NEXT:    vst %v0, 0(%r2), 3
; Z13-NEXT:    br %r14
  %sum = add i128 %a, %b
  %cmp = icmp ugt i128 %b, %sum
  %ext = zext i1 %cmp to i128
  ret i128 %ext
}

define i128 @i128_addc_xor(i128 %a, i128 %b) {
; BASELINE-LABEL: i128_addc_xor:
; BASELINE:       # %bb.0:
; BASELINE-NEXT:    lg %r0, 8(%r4)
; BASELINE-NEXT:    lg %r1, 0(%r4)
; BASELINE-NEXT:    alg %r0, 8(%r3)
; BASELINE-NEXT:    alcg %r1, 0(%r3)
; BASELINE-NEXT:    ipm %r0
; BASELINE-NEXT:    risbg %r0, %r0, 63, 191, 35
; BASELINE-NEXT:    stg %r0, 8(%r2)
; BASELINE-NEXT:    mvghi 0(%r2), 0
; BASELINE-NEXT:    br %r14
;
; Z13-LABEL: i128_addc_xor:
; Z13:       # %bb.0:
; Z13-NEXT:    vl %v0, 0(%r3), 3
; Z13-NEXT:    vl %v1, 0(%r4), 3
; Z13-NEXT:    vaccq %v0, %v1, %v0
; Z13-NEXT:    vst %v0, 0(%r2), 3
; Z13-NEXT:    br %r14
  %b.not = xor i128 %b, -1
  %cmp = icmp ugt i128 %a, %b.not
  %ext = zext i1 %cmp to i128
  ret i128 %ext
}

define i128 @i128_addc_xor_inv(i128 %a, i128 %b) {
; BASELINE-LABEL: i128_addc_xor_inv:
; BASELINE:       # %bb.0:
; BASELINE-NEXT:    stmg %r14, %r15, 112(%r15)
; BASELINE-NEXT:    .cfi_offset %r14, -48
; BASELINE-NEXT:    .cfi_offset %r15, -40
; BASELINE-NEXT:    lg %r5, 0(%r3)
; BASELINE-NEXT:    lghi %r14, -1
; BASELINE-NEXT:    xg %r14, 0(%r4)
; BASELINE-NEXT:    lghi %r1, -1
; BASELINE-NEXT:    xg %r1, 8(%r4)
; BASELINE-NEXT:    clgr %r5, %r14
; BASELINE-NEXT:    ipm %r0
; BASELINE-NEXT:    clg %r1, 8(%r3)
; BASELINE-NEXT:    ipm %r1
; BASELINE-NEXT:    cgrjlh %r5, %r14, .LBB7_2
; BASELINE-NEXT:  # %bb.1:
; BASELINE-NEXT:    xilf %r1, 4294967295
; BASELINE-NEXT:    risbg %r0, %r1, 63, 191, 36
; BASELINE-NEXT:    j .LBB7_3
; BASELINE-NEXT:  .LBB7_2:
; BASELINE-NEXT:    afi %r0, -536870912
; BASELINE-NEXT:    srl %r0, 31
; BASELINE-NEXT:  .LBB7_3:
; BASELINE-NEXT:    llgfr %r0, %r0
; BASELINE-NEXT:    stg %r0, 8(%r2)
; BASELINE-NEXT:    mvghi 0(%r2), 0
; BASELINE-NEXT:    lmg %r14, %r15, 112(%r15)
; BASELINE-NEXT:    br %r14
;
; Z13-LABEL: i128_addc_xor_inv:
; Z13:       # %bb.0:
; Z13-NEXT:    vl %v1, 0(%r4), 3
; Z13-NEXT:    vl %v0, 0(%r3), 3
; Z13-NEXT:    vno %v1, %v1, %v1
; Z13-NEXT:    vscbiq %v0, %v1, %v0
; Z13-NEXT:    vst %v0, 0(%r2), 3
; Z13-NEXT:    br %r14
  %b.not = xor i128 %b, -1
  %cmp = icmp ule i128 %a, %b.not
  %ext = zext i1 %cmp to i128
  ret i128 %ext
}
