; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mcpu=ppc -mtriple=powerpc64-unknown-linux-gnu < %s | FileCheck %s

define i8 @atomicrmw_usub_cond_i8(ptr %ptr, i8 %val) {
; CHECK-LABEL: atomicrmw_usub_cond_i8:
; CHECK:       # %bb.0:
; CHECK-NEXT:    sync
; CHECK-NEXT:    rldicr 5, 3, 0, 61
; CHECK-NEXT:    not     3, 3
; CHECK-NEXT:    li 6, 255
; CHECK-NEXT:    lwz 8, 0(5)
; CHECK-NEXT:    rlwinm 3, 3, 3, 27, 28
; CHECK-NEXT:    slw 6, 6, 3
; CHECK-NEXT:    not     6, 6
; CHECK-NEXT:    clrlwi  7, 4, 24
; CHECK-NEXT:    b .LBB0_2
; CHECK-NEXT:  .LBB0_1:                                # %cmpxchg.nostore
; CHECK-NEXT:                                          #   in Loop: Header=BB0_2 Depth=1
; CHECK-NEXT:    mr      8, 9
; CHECK-NEXT:  .LBB0_2:                                # %atomicrmw.start
; CHECK-NEXT:                                          # =>This Loop Header: Depth=1
; CHECK-NEXT:                                          #     Child Loop BB0_5 Depth 2
; CHECK-NEXT:    srw 9, 8, 3
; CHECK-NEXT:    clrlwi  10, 9, 24
; CHECK-NEXT:    cmplw   10, 7
; CHECK-NEXT:    blt     0, .LBB0_4
; CHECK-NEXT:  # %bb.3:                                #   in Loop: Header=BB0_2 Depth=1
; CHECK-NEXT:    sub     9, 9, 4
; CHECK-NEXT:  .LBB0_4:                                # %atomicrmw.start
; CHECK-NEXT:                                          #   in Loop: Header=BB0_2 Depth=1
; CHECK-NEXT:    clrlwi  9, 9, 24
; CHECK-NEXT:    slw 9, 9, 3
; CHECK-NEXT:    and 10, 8, 6
; CHECK-NEXT:    or 10, 10, 9
; CHECK-NEXT:  .LBB0_5:                                # %cmpxchg.start
; CHECK-NEXT:                                          #   Parent Loop BB0_2 Depth=1
; CHECK-NEXT:                                          # =>  This Inner Loop Header: Depth=2
; CHECK-NEXT:    lwarx 9, 0, 5
; CHECK-NEXT:    cmplw   9, 8
; CHECK-NEXT:    bne     0, .LBB0_1
; CHECK-NEXT:  # %bb.6:                                # %cmpxchg.fencedstore
; CHECK-NEXT:                                          #   in Loop: Header=BB0_5 Depth=2
; CHECK-NEXT:    stwcx. 10, 0, 5
; CHECK-NEXT:    bne     0, .LBB0_5
; CHECK-NEXT:  # %bb.7:
; CHECK-NEXT:    mr      8, 9
; CHECK-NEXT:  # %bb.8:                                # %atomicrmw.end
; CHECK-NEXT:    srw 3, 9, 3
; CHECK-NEXT:    lwsync
; CHECK-NEXT:    blr
  %result = atomicrmw usub_cond ptr %ptr, i8 %val seq_cst
  ret i8 %result
}

define i16 @atomicrmw_usub_cond_i16(ptr %ptr, i16 %val) {
; CHECK-LABEL: atomicrmw_usub_cond_i16:
; CHECK:       # %bb.0:
; CHECK-NEXT:    sync
; CHECK-NEXT:    rldicr 5, 3, 0, 61
; CHECK-NEXT:    clrlwi  3, 3, 30
; CHECK-NEXT:    lis 6, 0
; CHECK-NEXT:    xori 3, 3, 2
; CHECK-NEXT:    lwz 8, 0(5)
; CHECK-NEXT:    ori 6, 6, 65535
; CHECK-NEXT:    slwi 3, 3, 3
; CHECK-NEXT:    slw 6, 6, 3
; CHECK-NEXT:    not     6, 6
; CHECK-NEXT:    clrlwi  7, 4, 16
; CHECK-NEXT:    b .LBB1_2
; CHECK-NEXT:  .LBB1_1:                                # %cmpxchg.nostore
; CHECK-NEXT:                                          #   in Loop: Header=BB1_2 Depth=1
; CHECK-NEXT:    mr      8, 9
; CHECK-NEXT:  .LBB1_2:                                # %atomicrmw.start
; CHECK-NEXT:                                          # =>This Loop Header: Depth=1
; CHECK-NEXT:                                          #     Child Loop BB1_5 Depth 2
; CHECK-NEXT:    srw 9, 8, 3
; CHECK-NEXT:    clrlwi  10, 9, 16
; CHECK-NEXT:    cmplw   10, 7
; CHECK-NEXT:    blt     0, .LBB1_4
; CHECK-NEXT:  # %bb.3:                                #   in Loop: Header=BB1_2 Depth=1
; CHECK-NEXT:    sub     9, 9, 4
; CHECK-NEXT:  .LBB1_4:                                # %atomicrmw.start
; CHECK-NEXT:                                          #   in Loop: Header=BB1_2 Depth=1
; CHECK-NEXT:    clrlwi  9, 9, 16
; CHECK-NEXT:    slw 9, 9, 3
; CHECK-NEXT:    and 10, 8, 6
; CHECK-NEXT:    or 10, 10, 9
; CHECK-NEXT:  .LBB1_5:                                # %cmpxchg.start
; CHECK-NEXT:                                          #   Parent Loop BB1_2 Depth=1
; CHECK-NEXT:                                          # =>  This Inner Loop Header: Depth=2
; CHECK-NEXT:    lwarx 9, 0, 5
; CHECK-NEXT:    cmplw   9, 8
; CHECK-NEXT:    bne     0, .LBB1_1
; CHECK-NEXT:  # %bb.6:                                # %cmpxchg.fencedstore
; CHECK-NEXT:                                          #   in Loop: Header=BB1_5 Depth=2
; CHECK-NEXT:    stwcx. 10, 0, 5
; CHECK-NEXT:    bne     0, .LBB1_5
; CHECK-NEXT:  # %bb.7:
; CHECK-NEXT:    mr      8, 9
; CHECK-NEXT:  # %bb.8:                                # %atomicrmw.end
; CHECK-NEXT:    srw 3, 9, 3
; CHECK-NEXT:    lwsync
; CHECK-NEXT:    blr
  %result = atomicrmw usub_cond ptr %ptr, i16 %val seq_cst
  ret i16 %result
}

define i32 @atomicrmw_usub_cond_i32(ptr %ptr, i32 %val) {
; CHECK-LABEL: atomicrmw_usub_cond_i32:
; CHECK:       # %bb.0:
; CHECK-NEXT:    sync
; CHECK-NEXT:    lwz 6, 0(3)
; CHECK-NEXT:    b .LBB2_2
; CHECK-NEXT:  .LBB2_1:                                # %cmpxchg.nostore
; CHECK-NEXT:                                          #   in Loop: Header=BB2_2 Depth=1
; CHECK-NEXT:    mr      6, 5
; CHECK-NEXT:  .LBB2_2:                                # %atomicrmw.start
; CHECK-NEXT:                                          # =>This Loop Header: Depth=1
; CHECK-NEXT:                                          #     Child Loop BB2_5 Depth 2
; CHECK-NEXT:    cmplw   6, 4
; CHECK-NEXT:    bge 0, .LBB2_4
; CHECK-NEXT:  # %bb.3:                                # %atomicrmw.start
; CHECK-NEXT:                                          #   in Loop: Header=BB2_2 Depth=1
; CHECK-NEXT:    mr      7, 6
; CHECK-NEXT:    b .LBB2_5
; CHECK-NEXT:  .LBB2_4:                                #   in Loop: Header=BB2_2 Depth=1
; CHECK-NEXT:    sub     7, 6, 4
; CHECK-NEXT:  .LBB2_5:                                # %cmpxchg.start
; CHECK-NEXT:                                          #   Parent Loop BB2_2 Depth=1
; CHECK-NEXT:                                          # =>  This Inner Loop Header: Depth=2
; CHECK-NEXT:    lwarx 5, 0, 3
; CHECK-NEXT:    cmplw   5, 6
; CHECK-NEXT:    bne     0, .LBB2_1
; CHECK-NEXT:  # %bb.6:                                # %cmpxchg.fencedstore
; CHECK-NEXT:                                          #   in Loop: Header=BB2_5 Depth=2
; CHECK-NEXT:    stwcx. 7, 0, 3
; CHECK-NEXT:    bne     0, .LBB2_5
; CHECK-NEXT:  # %bb.7:
; CHECK-NEXT:    mr      6, 5
; CHECK-NEXT:  # %bb.8:                                # %atomicrmw.end
; CHECK-NEXT:    mr 3, 5
; CHECK-NEXT:    lwsync
; CHECK-NEXT:    blr
  %result = atomicrmw usub_cond ptr %ptr, i32 %val seq_cst
  ret i32 %result
}

define i64 @atomicrmw_usub_cond_i64(ptr %ptr, i64 %val) {
; CHECK-LABEL: atomicrmw_usub_cond_i64:
; CHECK:       # %bb.0:
; CHECK-NEXT:    sync
; CHECK-NEXT:    ld 6, 0(3)
; CHECK-NEXT:    b .LBB3_2
; CHECK-NEXT:  .LBB3_1:                                # %cmpxchg.nostore
; CHECK-NEXT:                                          #   in Loop: Header=BB3_2 Depth=1
; CHECK-NEXT:    mr      6, 5
; CHECK-NEXT:  .LBB3_2:                                # %atomicrmw.start
; CHECK-NEXT:                                          # =>This Loop Header: Depth=1
; CHECK-NEXT:                                          #     Child Loop BB3_5 Depth 2
; CHECK-NEXT:    cmpld   6, 4
; CHECK-NEXT:    bge 0, .LBB3_4
; CHECK-NEXT:  # %bb.3:                                # %atomicrmw.start
; CHECK-NEXT:                                          #   in Loop: Header=BB3_2 Depth=1
; CHECK-NEXT:    mr      7, 6
; CHECK-NEXT:    b .LBB3_5
; CHECK-NEXT:  .LBB3_4:                                #   in Loop: Header=BB3_2 Depth=1
; CHECK-NEXT:    sub     7, 6, 4
; CHECK-NEXT:  .LBB3_5:                                # %cmpxchg.start
; CHECK-NEXT:                                          #   Parent Loop BB3_2 Depth=1
; CHECK-NEXT:                                          # =>  This Inner Loop Header: Depth=2
; CHECK-NEXT:    ldarx 5, 0, 3
; CHECK-NEXT:    cmpld   5, 6
; CHECK-NEXT:    bne     0, .LBB3_1
; CHECK-NEXT:  # %bb.6:                                # %cmpxchg.fencedstore
; CHECK-NEXT:                                          #   in Loop: Header=BB3_5 Depth=2
; CHECK-NEXT:    stdcx. 7, 0, 3
; CHECK-NEXT:    bne     0, .LBB3_5
; CHECK-NEXT:  # %bb.7:
; CHECK-NEXT:    mr      6, 5
; CHECK-NEXT:  # %bb.8:                                # %atomicrmw.end
; CHECK-NEXT:    mr 3, 5
; CHECK-NEXT:    lwsync
; CHECK-NEXT:    blr
  %result = atomicrmw usub_cond ptr %ptr, i64 %val seq_cst
  ret i64 %result
}

define i8 @atomicrmw_usub_sat_i8(ptr %ptr, i8 %val) {
; CHECK-LABEL: atomicrmw_usub_sat_i8:
; CHECK:       # %bb.0:
; CHECK-NEXT:    sync
; CHECK-NEXT:    rldicr 5, 3, 0, 61
; CHECK-NEXT:    not     3, 3
; CHECK-NEXT:    li 6, 255
; CHECK-NEXT:    lwz 7, 0(5)
; CHECK-NEXT:    rlwinm 3, 3, 3, 27, 28
; CHECK-NEXT:    slw 6, 6, 3
; CHECK-NEXT:    not     6, 6
; CHECK-NEXT:    clrlwi  4, 4, 24
; CHECK-NEXT:    b .LBB4_2
; CHECK-NEXT:  .LBB4_1:                                # %cmpxchg.nostore
; CHECK-NEXT:                                          #   in Loop: Header=BB4_2 Depth=1
; CHECK-NEXT:    mr      7, 8
; CHECK-NEXT:  .LBB4_2:                                # %atomicrmw.start
; CHECK-NEXT:                                          # =>This Loop Header: Depth=1
; CHECK-NEXT:                                          #     Child Loop BB4_5 Depth 2
; CHECK-NEXT:    srw 8, 7, 3
; CHECK-NEXT:    clrlwi  9, 8, 24
; CHECK-NEXT:    sub     8, 9, 4
; CHECK-NEXT:    cmplw   8, 9
; CHECK-NEXT:    li 9, 0
; CHECK-NEXT:    bgt     0, .LBB4_4
; CHECK-NEXT:  # %bb.3:                                # %atomicrmw.start
; CHECK-NEXT:                                          #   in Loop: Header=BB4_2 Depth=1
; CHECK-NEXT:    mr      9, 8
; CHECK-NEXT:  .LBB4_4:                                # %atomicrmw.start
; CHECK-NEXT:                                          #   in Loop: Header=BB4_2 Depth=1
; CHECK-NEXT:    slw 8, 9, 3
; CHECK-NEXT:    and 9, 7, 6
; CHECK-NEXT:    or 9, 9, 8
; CHECK-NEXT:  .LBB4_5:                                # %cmpxchg.start
; CHECK-NEXT:                                          #   Parent Loop BB4_2 Depth=1
; CHECK-NEXT:                                          # =>  This Inner Loop Header: Depth=2
; CHECK-NEXT:    lwarx 8, 0, 5
; CHECK-NEXT:    cmplw   8, 7
; CHECK-NEXT:    bne     0, .LBB4_1
; CHECK-NEXT:  # %bb.6:                                # %cmpxchg.fencedstore
; CHECK-NEXT:                                          #   in Loop: Header=BB4_5 Depth=2
; CHECK-NEXT:    stwcx. 9, 0, 5
; CHECK-NEXT:    bne     0, .LBB4_5
; CHECK-NEXT:  # %bb.7:
; CHECK-NEXT:    mr      7, 8
; CHECK-NEXT:  # %bb.8:                                # %atomicrmw.end
; CHECK-NEXT:    srw 3, 8, 3
; CHECK-NEXT:    lwsync
; CHECK-NEXT:    blr
  %result = atomicrmw usub_sat ptr %ptr, i8 %val seq_cst
  ret i8 %result
}

define i16 @atomicrmw_usub_sat_i16(ptr %ptr, i16 %val) {
; CHECK-LABEL: atomicrmw_usub_sat_i16:
; CHECK:       # %bb.0:
; CHECK-NEXT:    sync
; CHECK-NEXT:    rldicr 5, 3, 0, 61
; CHECK-NEXT:    clrlwi  3, 3, 30
; CHECK-NEXT:    lis 6, 0
; CHECK-NEXT:    xori 3, 3, 2
; CHECK-NEXT:    lwz 7, 0(5)
; CHECK-NEXT:    ori 6, 6, 65535
; CHECK-NEXT:    slwi 3, 3, 3
; CHECK-NEXT:    slw 6, 6, 3
; CHECK-NEXT:    not     6, 6
; CHECK-NEXT:    clrlwi  4, 4, 16
; CHECK-NEXT:    b .LBB5_2
; CHECK-NEXT:  .LBB5_1:                                # %cmpxchg.nostore
; CHECK-NEXT:                                          #   in Loop: Header=BB5_2 Depth=1
; CHECK-NEXT:    mr      7, 8
; CHECK-NEXT:  .LBB5_2:                                # %atomicrmw.start
; CHECK-NEXT:                                          # =>This Loop Header: Depth=1
; CHECK-NEXT:                                          #     Child Loop BB5_5 Depth 2
; CHECK-NEXT:    srw 8, 7, 3
; CHECK-NEXT:    clrlwi  9, 8, 16
; CHECK-NEXT:    sub     8, 9, 4
; CHECK-NEXT:    cmplw   8, 9
; CHECK-NEXT:    li 9, 0
; CHECK-NEXT:    bgt     0, .LBB5_4
; CHECK-NEXT:  # %bb.3:                                # %atomicrmw.start
; CHECK-NEXT:                                          #   in Loop: Header=BB5_2 Depth=1
; CHECK-NEXT:    mr      9, 8
; CHECK-NEXT:  .LBB5_4:                                # %atomicrmw.start
; CHECK-NEXT:                                          #   in Loop: Header=BB5_2 Depth=1
; CHECK-NEXT:    slw 8, 9, 3
; CHECK-NEXT:    and 9, 7, 6
; CHECK-NEXT:    or 9, 9, 8
; CHECK-NEXT:  .LBB5_5:                                # %cmpxchg.start
; CHECK-NEXT:                                          #   Parent Loop BB5_2 Depth=1
; CHECK-NEXT:                                          # =>  This Inner Loop Header: Depth=2
; CHECK-NEXT:    lwarx 8, 0, 5
; CHECK-NEXT:    cmplw   8, 7
; CHECK-NEXT:    bne     0, .LBB5_1
; CHECK-NEXT:  # %bb.6:                                # %cmpxchg.fencedstore
; CHECK-NEXT:                                          #   in Loop: Header=BB5_5 Depth=2
; CHECK-NEXT:    stwcx. 9, 0, 5
; CHECK-NEXT:    bne     0, .LBB5_5
; CHECK-NEXT:  # %bb.7:
; CHECK-NEXT:    mr      7, 8
; CHECK-NEXT:  # %bb.8:                                # %atomicrmw.end
; CHECK-NEXT:    srw 3, 8, 3
; CHECK-NEXT:    lwsync
; CHECK-NEXT:    blr
  %result = atomicrmw usub_sat ptr %ptr, i16 %val seq_cst
  ret i16 %result
}

define i32 @atomicrmw_usub_sat_i32(ptr %ptr, i32 %val) {
; CHECK-LABEL: atomicrmw_usub_sat_i32:
; CHECK:       # %bb.0:
; CHECK-NEXT:    sync
; CHECK-NEXT:    lwz 6, 0(3)
; CHECK-NEXT:    b .LBB6_2
; CHECK-NEXT:  .LBB6_1:                                # %cmpxchg.nostore
; CHECK-NEXT:                                          #   in Loop: Header=BB6_2 Depth=1
; CHECK-NEXT:    mr      6, 5
; CHECK-NEXT:  .LBB6_2:                                # %atomicrmw.start
; CHECK-NEXT:                                          # =>This Loop Header: Depth=1
; CHECK-NEXT:                                          #     Child Loop BB6_4 Depth 2
; CHECK-NEXT:    sub     5, 6, 4
; CHECK-NEXT:    cmplw   5, 6
; CHECK-NEXT:    li 7, 0
; CHECK-NEXT:    bgt     0, .LBB6_4
; CHECK-NEXT:  # %bb.3:                                # %atomicrmw.start
; CHECK-NEXT:                                          #   in Loop: Header=BB6_2 Depth=1
; CHECK-NEXT:    mr      7, 5
; CHECK-NEXT:  .LBB6_4:                                # %cmpxchg.start
; CHECK-NEXT:                                          #   Parent Loop BB6_2 Depth=1
; CHECK-NEXT:                                          # =>  This Inner Loop Header: Depth=2
; CHECK-NEXT:    lwarx 5, 0, 3
; CHECK-NEXT:    cmplw   5, 6
; CHECK-NEXT:    bne     0, .LBB6_1
; CHECK-NEXT:  # %bb.5:                                # %cmpxchg.fencedstore
; CHECK-NEXT:                                          #   in Loop: Header=BB6_4 Depth=2
; CHECK-NEXT:    stwcx. 7, 0, 3
; CHECK-NEXT:    bne     0, .LBB6_4
; CHECK-NEXT:  # %bb.6:
; CHECK-NEXT:    mr      6, 5
; CHECK-NEXT:  # %bb.7:                                # %atomicrmw.end
; CHECK-NEXT:    mr 3, 5
; CHECK-NEXT:    lwsync
; CHECK-NEXT:    blr
  %result = atomicrmw usub_sat ptr %ptr, i32 %val seq_cst
  ret i32 %result
}

define i64 @atomicrmw_usub_sat_i64(ptr %ptr, i64 %val) {
; CHECK-LABEL: atomicrmw_usub_sat_i64:
; CHECK:       # %bb.0:
; CHECK-NEXT:    sync
; CHECK-NEXT:    ld 6, 0(3)
; CHECK-NEXT:    b .LBB7_2
; CHECK-NEXT:  .LBB7_1:                                # %cmpxchg.nostore
; CHECK-NEXT:                                          #   in Loop: Header=BB7_2 Depth=1
; CHECK-NEXT:    mr      6, 5
; CHECK-NEXT:  .LBB7_2:                                # %atomicrmw.start
; CHECK-NEXT:                                          # =>This Loop Header: Depth=1
; CHECK-NEXT:                                          #     Child Loop BB7_4 Depth 2
; CHECK-NEXT:    subc    5, 6, 4
; CHECK-NEXT:    li 7, 0
; CHECK-NEXT:    addze. 8, 7
; CHECK-NEXT:    beq     0, .LBB7_4
; CHECK-NEXT:  # %bb.3:                                # %atomicrmw.start
; CHECK-NEXT:                                          #   in Loop: Header=BB7_2 Depth=1
; CHECK-NEXT:    mr      7, 5
; CHECK-NEXT:  .LBB7_4:                                # %cmpxchg.start
; CHECK-NEXT:                                          #   Parent Loop BB7_2 Depth=1
; CHECK-NEXT:                                          # =>  This Inner Loop Header: Depth=2
; CHECK-NEXT:    ldarx 5, 0, 3
; CHECK-NEXT:    cmpld   5, 6
; CHECK-NEXT:    bne     0, .LBB7_1
; CHECK-NEXT:  # %bb.5:                                # %cmpxchg.fencedstore
; CHECK-NEXT:                                          #   in Loop: Header=BB7_4 Depth=2
; CHECK-NEXT:    stdcx. 7, 0, 3
; CHECK-NEXT:    bne     0, .LBB7_4
; CHECK-NEXT:  # %bb.6:
; CHECK-NEXT:    mr      6, 5
; CHECK-NEXT:  # %bb.7:                                # %atomicrmw.end
; CHECK-NEXT:    mr 3, 5
; CHECK-NEXT:    lwsync
; CHECK-NEXT:    blr
  %result = atomicrmw usub_sat ptr %ptr, i64 %val seq_cst
  ret i64 %result
}
