; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefixes=X86
; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefixes=X64

define i32 @PR40483_add1(ptr, i32) nounwind {
; X86-LABEL: PR40483_add1:
; X86:       # %bb.0:
; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
; X86-NEXT:    movl (%ecx), %eax
; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
; X86-NEXT:    movl %eax, (%ecx)
; X86-NEXT:    jae .LBB0_2
; X86-NEXT:  # %bb.1:
; X86-NEXT:    xorl %eax, %eax
; X86-NEXT:  .LBB0_2:
; X86-NEXT:    retl
;
; X64-LABEL: PR40483_add1:
; X64:       # %bb.0:
; X64-NEXT:    xorl %eax, %eax
; X64-NEXT:    addl (%rdi), %esi
; X64-NEXT:    movl %esi, (%rdi)
; X64-NEXT:    cmovael %esi, %eax
; X64-NEXT:    retq
  %3 = load i32, ptr %0, align 8
  %4 = tail call { i8, i32 } @llvm.x86.addcarry.32(i8 0, i32 %3, i32 %1)
  %5 = extractvalue { i8, i32 } %4, 1
  store i32 %5, ptr %0, align 8
  %6 = extractvalue { i8, i32 } %4, 0
  %7 = icmp eq i8 %6, 0
  %8 = add i32 %1, %3
  %9 = or i32 %5, %8
  %10 = select i1 %7, i32 %9, i32 0
  ret i32 %10
}

define i32 @PR40483_add2(ptr, i32) nounwind {
; X86-LABEL: PR40483_add2:
; X86:       # %bb.0:
; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
; X86-NEXT:    movl (%edx), %ecx
; X86-NEXT:    xorl %eax, %eax
; X86-NEXT:    addl {{[0-9]+}}(%esp), %ecx
; X86-NEXT:    movl %ecx, (%edx)
; X86-NEXT:    jae .LBB1_2
; X86-NEXT:  # %bb.1:
; X86-NEXT:    movl %ecx, %eax
; X86-NEXT:  .LBB1_2:
; X86-NEXT:    retl
;
; X64-LABEL: PR40483_add2:
; X64:       # %bb.0:
; X64-NEXT:    xorl %eax, %eax
; X64-NEXT:    addl (%rdi), %esi
; X64-NEXT:    movl %esi, (%rdi)
; X64-NEXT:    cmovbl %esi, %eax
; X64-NEXT:    retq
  %3 = load i32, ptr %0, align 8
  %4 = tail call { i8, i32 } @llvm.x86.addcarry.32(i8 0, i32 %3, i32 %1)
  %5 = extractvalue { i8, i32 } %4, 1
  store i32 %5, ptr %0, align 8
  %6 = extractvalue { i8, i32 } %4, 0
  %7 = icmp eq i8 %6, 0
  %8 = add i32 %3, %1
  %9 = or i32 %5, %8
  %10 = select i1 %7, i32 0, i32 %9
  ret i32 %10
}

define i32 @adc_merge_constants(i32 %a0) nounwind {
; X86-LABEL: adc_merge_constants:
; X86:       # %bb.0:
; X86-NEXT:    xorl %eax, %eax
; X86-NEXT:    btl $11, {{[0-9]+}}(%esp)
; X86-NEXT:    adcl $54, %eax
; X86-NEXT:    retl
;
; X64-LABEL: adc_merge_constants:
; X64:       # %bb.0:
; X64-NEXT:    xorl %eax, %eax
; X64-NEXT:    btl $11, %edi
; X64-NEXT:    adcl $54, %eax
; X64-NEXT:    retq
  %bit = lshr i32 %a0, 11
  %mask = and i32 %bit, 1
  %isz = trunc i32 %mask to i8
  %adc = tail call { i8, i32 } @llvm.x86.addcarry.32(i8 %isz, i32 55, i32 -1)
  %sum = extractvalue { i8, i32 } %adc, 1
  ret i32 %sum
}

define i32 @adc_merge_sub(i32 %a0) nounwind {
; X86-LABEL: adc_merge_sub:
; X86:       # %bb.0:
; X86-NEXT:    pushl %edi
; X86-NEXT:    pushl %esi
; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
; X86-NEXT:    xorl %eax, %eax
; X86-NEXT:    addl $42, %edi
; X86-NEXT:    setb %al
; X86-NEXT:    movl %edi, %esi
; X86-NEXT:    negl %esi
; X86-NEXT:    pushl %eax
; X86-NEXT:    calll use@PLT
; X86-NEXT:    addl $4, %esp
; X86-NEXT:    xorl %edi, %esi
; X86-NEXT:    movl %esi, %eax
; X86-NEXT:    popl %esi
; X86-NEXT:    popl %edi
; X86-NEXT:    retl
;
; X64-LABEL: adc_merge_sub:
; X64:       # %bb.0:
; X64-NEXT:    pushq %rbp
; X64-NEXT:    pushq %rbx
; X64-NEXT:    pushq %rax
; X64-NEXT:    movl %edi, %ebx
; X64-NEXT:    xorl %edi, %edi
; X64-NEXT:    addl $42, %ebx
; X64-NEXT:    setb %dil
; X64-NEXT:    movl %ebx, %ebp
; X64-NEXT:    negl %ebp
; X64-NEXT:    callq use@PLT
; X64-NEXT:    xorl %ebx, %ebp
; X64-NEXT:    movl %ebp, %eax
; X64-NEXT:    addq $8, %rsp
; X64-NEXT:    popq %rbx
; X64-NEXT:    popq %rbp
; X64-NEXT:    retq
  %adc = tail call { i8, i32 } @llvm.x86.addcarry.32(i8 0, i32 %a0, i32 42)
  %carry = extractvalue { i8, i32 } %adc, 0
  call void @use(i8 %carry)
  %sum = extractvalue { i8, i32 } %adc, 1
  %sub = sub i32 -42, %a0
  %result = xor i32 %sum, %sub
  ret i32 %result
}

declare { i8, i32 } @llvm.x86.addcarry.32(i8, i32, i32)
declare void @use(i8)
