; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple x86_64-pc-linux < %s | FileCheck %s

define i8 @atomicrmw_uinc_wrap_i8(ptr %ptr, i8 %val) {
; CHECK-LABEL: atomicrmw_uinc_wrap_i8:
; CHECK:       # %bb.0:
; CHECK-NEXT:    movzbl (%rdi), %eax
; CHECK-NEXT:    xorl %ecx, %ecx
; CHECK-NEXT:    .p2align 4, 0x90
; CHECK-NEXT:  .LBB0_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    leal 1(%rax), %edx
; CHECK-NEXT:    cmpb %sil, %al
; CHECK-NEXT:    movzbl %dl, %edx
; CHECK-NEXT:    cmovael %ecx, %edx
; CHECK-NEXT:    # kill: def $al killed $al killed $rax
; CHECK-NEXT:    lock cmpxchgb %dl, (%rdi)
; CHECK-NEXT:    # kill: def $al killed $al def $rax
; CHECK-NEXT:    jne .LBB0_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    # kill: def $al killed $al killed $rax
; CHECK-NEXT:    retq
  %result = atomicrmw uinc_wrap ptr %ptr, i8 %val seq_cst
  ret i8 %result
}

define i16 @atomicrmw_uinc_wrap_i16(ptr %ptr, i16 %val) {
; CHECK-LABEL: atomicrmw_uinc_wrap_i16:
; CHECK:       # %bb.0:
; CHECK-NEXT:    movzwl (%rdi), %eax
; CHECK-NEXT:    xorl %ecx, %ecx
; CHECK-NEXT:    .p2align 4, 0x90
; CHECK-NEXT:  .LBB1_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    leal 1(%rax), %edx
; CHECK-NEXT:    cmpw %si, %ax
; CHECK-NEXT:    cmovael %ecx, %edx
; CHECK-NEXT:    # kill: def $ax killed $ax killed $rax
; CHECK-NEXT:    lock cmpxchgw %dx, (%rdi)
; CHECK-NEXT:    # kill: def $ax killed $ax def $rax
; CHECK-NEXT:    jne .LBB1_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    # kill: def $ax killed $ax killed $rax
; CHECK-NEXT:    retq
  %result = atomicrmw uinc_wrap ptr %ptr, i16 %val seq_cst
  ret i16 %result
}

define i32 @atomicrmw_uinc_wrap_i32(ptr %ptr, i32 %val) {
; CHECK-LABEL: atomicrmw_uinc_wrap_i32:
; CHECK:       # %bb.0:
; CHECK-NEXT:    movl (%rdi), %eax
; CHECK-NEXT:    xorl %ecx, %ecx
; CHECK-NEXT:    .p2align 4, 0x90
; CHECK-NEXT:  .LBB2_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    leal 1(%rax), %edx
; CHECK-NEXT:    cmpl %esi, %eax
; CHECK-NEXT:    cmovael %ecx, %edx
; CHECK-NEXT:    # kill: def $eax killed $eax killed $rax
; CHECK-NEXT:    lock cmpxchgl %edx, (%rdi)
; CHECK-NEXT:    # kill: def $eax killed $eax def $rax
; CHECK-NEXT:    jne .LBB2_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    # kill: def $eax killed $eax killed $rax
; CHECK-NEXT:    retq
  %result = atomicrmw uinc_wrap ptr %ptr, i32 %val seq_cst
  ret i32 %result
}

define i64 @atomicrmw_uinc_wrap_i64(ptr %ptr, i64 %val) {
; CHECK-LABEL: atomicrmw_uinc_wrap_i64:
; CHECK:       # %bb.0:
; CHECK-NEXT:    movq (%rdi), %rax
; CHECK-NEXT:    xorl %ecx, %ecx
; CHECK-NEXT:    .p2align 4, 0x90
; CHECK-NEXT:  .LBB3_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    leaq 1(%rax), %rdx
; CHECK-NEXT:    cmpq %rsi, %rax
; CHECK-NEXT:    cmovaeq %rcx, %rdx
; CHECK-NEXT:    lock cmpxchgq %rdx, (%rdi)
; CHECK-NEXT:    jne .LBB3_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    retq
  %result = atomicrmw uinc_wrap ptr %ptr, i64 %val seq_cst
  ret i64 %result
}

define i8 @atomicrmw_udec_wrap_i8(ptr %ptr, i8 %val) {
; CHECK-LABEL: atomicrmw_udec_wrap_i8:
; CHECK:       # %bb.0:
; CHECK-NEXT:    movzbl (%rdi), %eax
; CHECK-NEXT:    movzbl %sil, %ecx
; CHECK-NEXT:    .p2align 4, 0x90
; CHECK-NEXT:  .LBB4_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    movl %eax, %edx
; CHECK-NEXT:    subb $1, %dl
; CHECK-NEXT:    cmpb %cl, %al
; CHECK-NEXT:    movzbl %dl, %edx
; CHECK-NEXT:    cmoval %ecx, %edx
; CHECK-NEXT:    cmpb $1, %al
; CHECK-NEXT:    cmovbl %ecx, %edx
; CHECK-NEXT:    lock cmpxchgb %dl, (%rdi)
; CHECK-NEXT:    jne .LBB4_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    retq
  %result = atomicrmw udec_wrap ptr %ptr, i8 %val seq_cst
  ret i8 %result
}

define i16 @atomicrmw_udec_wrap_i16(ptr %ptr, i16 %val) {
; CHECK-LABEL: atomicrmw_udec_wrap_i16:
; CHECK:       # %bb.0:
; CHECK-NEXT:    movzwl (%rdi), %eax
; CHECK-NEXT:    .p2align 4, 0x90
; CHECK-NEXT:  .LBB5_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    movl %eax, %ecx
; CHECK-NEXT:    subw $1, %cx
; CHECK-NEXT:    cmpw %si, %ax
; CHECK-NEXT:    cmoval %esi, %ecx
; CHECK-NEXT:    cmpw $1, %ax
; CHECK-NEXT:    cmovbl %esi, %ecx
; CHECK-NEXT:    lock cmpxchgw %cx, (%rdi)
; CHECK-NEXT:    jne .LBB5_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    retq
  %result = atomicrmw udec_wrap ptr %ptr, i16 %val seq_cst
  ret i16 %result
}

define i32 @atomicrmw_udec_wrap_i32(ptr %ptr, i32 %val) {
; CHECK-LABEL: atomicrmw_udec_wrap_i32:
; CHECK:       # %bb.0:
; CHECK-NEXT:    movl (%rdi), %eax
; CHECK-NEXT:    .p2align 4, 0x90
; CHECK-NEXT:  .LBB6_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    leal -1(%rax), %ecx
; CHECK-NEXT:    cmpl %esi, %eax
; CHECK-NEXT:    cmoval %esi, %ecx
; CHECK-NEXT:    cmpl $1, %eax
; CHECK-NEXT:    cmovbl %esi, %ecx
; CHECK-NEXT:    # kill: def $eax killed $eax killed $rax
; CHECK-NEXT:    lock cmpxchgl %ecx, (%rdi)
; CHECK-NEXT:    # kill: def $eax killed $eax def $rax
; CHECK-NEXT:    jne .LBB6_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    # kill: def $eax killed $eax killed $rax
; CHECK-NEXT:    retq
  %result = atomicrmw udec_wrap ptr %ptr, i32 %val seq_cst
  ret i32 %result
}

define i64 @atomicrmw_udec_wrap_i64(ptr %ptr, i64 %val) {
; CHECK-LABEL: atomicrmw_udec_wrap_i64:
; CHECK:       # %bb.0:
; CHECK-NEXT:    movq (%rdi), %rax
; CHECK-NEXT:    .p2align 4, 0x90
; CHECK-NEXT:  .LBB7_1: # %atomicrmw.start
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    leaq -1(%rax), %rcx
; CHECK-NEXT:    cmpq %rsi, %rax
; CHECK-NEXT:    cmovaq %rsi, %rcx
; CHECK-NEXT:    cmpq $1, %rax
; CHECK-NEXT:    cmovbq %rsi, %rcx
; CHECK-NEXT:    lock cmpxchgq %rcx, (%rdi)
; CHECK-NEXT:    jne .LBB7_1
; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
; CHECK-NEXT:    retq
  %result = atomicrmw udec_wrap ptr %ptr, i64 %val seq_cst
  ret i64 %result
}
