Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1875,6 +1875,18 @@ SDLoc(N), MVT::Glue)); } + // (addc X, (adde Y, 0, Carry)) -> (adde X, Y, Carry) + // if Y + 1 cannot overflow. + if (N1.getOpcode() == ISD::ADDE && + N1->hasOneUse() && + isNullConstant(N1.getOperand(1))) { + APInt YZero, YOne; + DAG.computeKnownBits(N1.getOperand(0), YZero, YOne); + if (YZero.getBoolValue()) + return DAG.getNode(ISD::ADDE, SDLoc(N), N->getVTList(), N0, + N1->getOperand(0), N1->getOperand(2)); + } + return SDValue(); } Index: test/CodeGen/X86/adde-carry.ll =================================================================== --- test/CodeGen/X86/adde-carry.ll +++ test/CodeGen/X86/adde-carry.ll @@ -89,24 +89,21 @@ define %scalar @pr31719(%scalar* nocapture readonly %this, %scalar %arg.b) { ; CHECK-LABEL: pr31719: ; CHECK: # BB#0: # %entry -; CHECK-NEXT: addq (%rsi), %rdx +; CHECK-NEXT: addq 8(%rsi), %rcx ; CHECK-NEXT: sbbq %r10, %r10 ; CHECK-NEXT: andl $1, %r10d -; CHECK-NEXT: addq 8(%rsi), %rcx -; CHECK-NEXT: sbbq %r11, %r11 -; CHECK-NEXT: andl $1, %r11d -; CHECK-NEXT: addq %r10, %rcx -; CHECK-NEXT: adcq $0, %r11 ; CHECK-NEXT: addq 16(%rsi), %r8 ; CHECK-NEXT: sbbq %rax, %rax ; CHECK-NEXT: andl $1, %eax -; CHECK-NEXT: addq %r11, %r8 +; CHECK-NEXT: addq (%rsi), %rdx +; CHECK-NEXT: adcq $0, %rcx +; CHECK-NEXT: adcq %r8, %r10 ; CHECK-NEXT: adcq $0, %rax ; CHECK-NEXT: addq 24(%rsi), %r9 ; CHECK-NEXT: addq %rax, %r9 ; CHECK-NEXT: movq %rdx, (%rdi) ; CHECK-NEXT: movq %rcx, 8(%rdi) -; CHECK-NEXT: movq %r8, 16(%rdi) +; CHECK-NEXT: movq %r10, 16(%rdi) ; CHECK-NEXT: movq %r9, 24(%rdi) ; CHECK-NEXT: movq %rdi, %rax ; CHECK-NEXT: retq