diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2602,6 +2602,14 @@ break; } + // Consider SETcc variants which affect carry flag only. + if (V.getOpcode() == ISD::SETCC) { + ISD::CondCode CC = cast(V.getOperand(2))->get(); + if (CC == ISD::SETULT) + return V; + return {}; + } + // If this is not a carry, return. if (V.getResNo() != 1) return SDValue(); diff --git a/llvm/test/CodeGen/X86/addcarry.ll b/llvm/test/CodeGen/X86/addcarry.ll --- a/llvm/test/CodeGen/X86/addcarry.ll +++ b/llvm/test/CodeGen/X86/addcarry.ll @@ -420,44 +420,31 @@ define i32 @add_U320_without_i128_add(%struct.U320* nocapture dereferenceable(40) %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5) { ; CHECK-LABEL: add_U320_without_i128_add: ; CHECK: # %bb.0: -; CHECK-NEXT: pushq %r14 -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: pushq %rbx -; CHECK-NEXT: .cfi_def_cfa_offset 24 -; CHECK-NEXT: .cfi_offset %rbx, -24 -; CHECK-NEXT: .cfi_offset %r14, -16 -; CHECK-NEXT: movq 16(%rdi), %rax -; CHECK-NEXT: leaq (%rax,%rcx), %r10 +; CHECK-NEXT: movq 16(%rdi), %r10 +; CHECK-NEXT: xorl %r11d, %r11d +; CHECK-NEXT: movq %r10, %rax +; CHECK-NEXT: addq %rcx, %rax +; CHECK-NEXT: setb %r11b ; CHECK-NEXT: addq %rsi, (%rdi) ; CHECK-NEXT: adcq %rdx, 8(%rdi) -; CHECK-NEXT: movq %rax, %rdx -; CHECK-NEXT: adcq %rcx, %rdx -; CHECK-NEXT: movq 24(%rdi), %r11 -; CHECK-NEXT: leaq (%r8,%r11), %r14 -; CHECK-NEXT: xorl %ebx, %ebx -; CHECK-NEXT: cmpq %r10, %rdx -; CHECK-NEXT: setb %bl -; CHECK-NEXT: addq %rcx, %rax -; CHECK-NEXT: adcq %r14, %rbx -; CHECK-NEXT: movq 32(%rdi), %r10 -; CHECK-NEXT: leaq (%r9,%r10), %rcx -; CHECK-NEXT: xorl %esi, %esi -; CHECK-NEXT: cmpq %r14, %rbx -; CHECK-NEXT: setb %sil -; CHECK-NEXT: addq %r11, %r8 -; CHECK-NEXT: adcq %rcx, %rsi +; CHECK-NEXT: adcq %rcx, %r10 +; CHECK-NEXT: xorl %ecx, %ecx +; CHECK-NEXT: addq 24(%rdi), %r8 +; CHECK-NEXT: setb %cl +; CHECK-NEXT: cmpq %rax, %r10 +; CHECK-NEXT: adcq %r8, %r11 +; CHECK-NEXT: movq 32(%rdi), %rdx +; CHECK-NEXT: leaq (%r9,%rdx), %rsi +; CHECK-NEXT: cmpq %r8, %r11 +; CHECK-NEXT: adcq %rsi, %rcx ; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpq %rcx, %rsi +; CHECK-NEXT: cmpq %rsi, %rcx ; CHECK-NEXT: setb %al -; CHECK-NEXT: addq %r10, %r9 -; CHECK-NEXT: movq %rdx, 16(%rdi) -; CHECK-NEXT: movq %rbx, 24(%rdi) -; CHECK-NEXT: movq %rsi, 32(%rdi) +; CHECK-NEXT: addq %rdx, %r9 +; CHECK-NEXT: movq %r10, 16(%rdi) +; CHECK-NEXT: movq %r11, 24(%rdi) +; CHECK-NEXT: movq %rcx, 32(%rdi) ; CHECK-NEXT: adcl $0, %eax -; CHECK-NEXT: popq %rbx -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: popq %r14 -; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq %7 = getelementptr inbounds %struct.U320, %struct.U320* %0, i64 0, i32 0, i64 0 %8 = load i64, i64* %7, align 8 diff --git a/llvm/test/CodeGen/X86/cmp-carry.ll b/llvm/test/CodeGen/X86/cmp-carry.ll --- a/llvm/test/CodeGen/X86/cmp-carry.ll +++ b/llvm/test/CodeGen/X86/cmp-carry.ll @@ -4,11 +4,9 @@ define i32 @cmp_carry_ult(i32 %a, i32 %b, i32 %x, i32 %y) { ; CHECK-LABEL: cmp_carry_ult: ; CHECK: # %bb.0: -; CHECK-NEXT: # kill: def $esi killed $esi def $rsi -; CHECK-NEXT: # kill: def $edi killed $edi def $rdi -; CHECK-NEXT: leal (%rdi,%rsi), %eax +; CHECK-NEXT: movl %edi, %eax ; CHECK-NEXT: cmpl %ecx, %edx -; CHECK-NEXT: adcl $0, %eax +; CHECK-NEXT: adcl %esi, %eax ; CHECK-NEXT: retq %s = add i32 %a, %b %k = icmp ult i32 %x, %y