Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2519,6 +2519,13 @@ if (SDValue Combined = visitADDCARRYLike(N1, N0, CarryIn, N)) return Combined; + // We want to avoid useless duplication. + SDValue Ops[] = {N1, N0, CarryIn}; + SDNode *CSENode = DAG.getNodeIfExists(ISD::ADDCARRY, N->getVTList(), Ops, + N->getFlags()); + if (CSENode) + return SDValue(CSENode, 0); + return SDValue(); } Index: test/CodeGen/X86/addcarry.ll =================================================================== --- test/CodeGen/X86/addcarry.ll +++ test/CodeGen/X86/addcarry.ll @@ -314,21 +314,13 @@ ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: movq %rdi, %rax ; CHECK-NEXT: addq (%rsi), %rdx -; CHECK-NEXT: movq 8(%rsi), %r11 -; CHECK-NEXT: adcq $0, %r11 -; CHECK-NEXT: setb %r10b -; CHECK-NEXT: movzbl %r10b, %edi -; CHECK-NEXT: addq %rcx, %r11 -; CHECK-NEXT: adcq 16(%rsi), %rdi -; CHECK-NEXT: setb %cl -; CHECK-NEXT: movzbl %cl, %ecx -; CHECK-NEXT: addq %r8, %rdi -; CHECK-NEXT: adcq 24(%rsi), %rcx -; CHECK-NEXT: addq %r9, %rcx -; CHECK-NEXT: movq %rdx, (%rax) -; CHECK-NEXT: movq %r11, 8(%rax) -; CHECK-NEXT: movq %rdi, 16(%rax) -; CHECK-NEXT: movq %rcx, 24(%rax) +; CHECK-NEXT: adcq 8(%rsi), %rcx +; CHECK-NEXT: adcq 16(%rsi), %r8 +; CHECK-NEXT: adcq 24(%rsi), %r9 +; CHECK-NEXT: movq %rdx, (%rdi) +; CHECK-NEXT: movq %rcx, 8(%rdi) +; CHECK-NEXT: movq %r8, 16(%rdi) +; CHECK-NEXT: movq %r9, 24(%rdi) ; CHECK-NEXT: retq entry: %0 = extractvalue %S %arg.b, 0 Index: test/CodeGen/X86/subcarry.ll =================================================================== --- test/CodeGen/X86/subcarry.ll +++ test/CodeGen/X86/subcarry.ll @@ -90,38 +90,23 @@ define %S @sub(%S* nocapture readonly %this, %S %arg.b) local_unnamed_addr { ; CHECK-LABEL: sub: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: pushq %rbx -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: .cfi_offset %rbx, -16 ; CHECK-NEXT: movq %rdi, %rax -; CHECK-NEXT: notq %rdx ; CHECK-NEXT: movq (%rsi), %rdi -; CHECK-NEXT: movq 8(%rsi), %r10 +; CHECK-NEXT: notq %rdx +; CHECK-NEXT: leaq 1(%rdi,%rdx), %r10 ; CHECK-NEXT: movb $1, %r11b ; CHECK-NEXT: addb $-1, %r11b -; CHECK-NEXT: leaq 1(%rdi,%rdx), %r11 -; CHECK-NEXT: adcq %rdx, %rdi +; CHECK-NEXT: adcq %rdi, %rdx ; CHECK-NEXT: notq %rcx -; CHECK-NEXT: setb %dl -; CHECK-NEXT: movq %rcx, %rdi -; CHECK-NEXT: adcq %r10, %rdi -; CHECK-NEXT: movq 16(%rsi), %rbx -; CHECK-NEXT: addb $255, %dl -; CHECK-NEXT: adcq %r10, %rcx +; CHECK-NEXT: adcq 8(%rsi), %rcx ; CHECK-NEXT: notq %r8 -; CHECK-NEXT: setb %cl -; CHECK-NEXT: movq %r8, %rdx -; CHECK-NEXT: adcq %rbx, %rdx -; CHECK-NEXT: addb $255, %cl -; CHECK-NEXT: adcq %rbx, %r8 +; CHECK-NEXT: adcq 16(%rsi), %r8 ; CHECK-NEXT: notq %r9 ; CHECK-NEXT: adcq 24(%rsi), %r9 -; CHECK-NEXT: movq %r11, (%rax) -; CHECK-NEXT: movq %rdi, 8(%rax) -; CHECK-NEXT: movq %rdx, 16(%rax) +; CHECK-NEXT: movq %r10, (%rax) +; CHECK-NEXT: movq %rcx, 8(%rax) +; CHECK-NEXT: movq %r8, 16(%rax) ; CHECK-NEXT: movq %r9, 24(%rax) -; CHECK-NEXT: popq %rbx -; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %0 = extractvalue %S %arg.b, 0