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 @@ -2966,8 +2966,11 @@ SDNode *N) { // Iff the flag result is dead: // (addcarry (add|uaddo X, Y), 0, Carry) -> (addcarry X, Y, Carry) + // Don't do this if the Carry comes from the uaddo. It won't remove the uaddo + // or the dependency between the instructions. if ((N0.getOpcode() == ISD::ADD || - (N0.getOpcode() == ISD::UADDO && N0.getResNo() == 0)) && + (N0.getOpcode() == ISD::UADDO && N0.getResNo() == 0 && + N0.getValue(1) != CarryIn)) && isNullConstant(N1) && !N->hasAnyUseOfValue(1)) return DAG.getNode(ISD::ADDCARRY, SDLoc(N), N->getVTList(), N0.getOperand(0), N0.getOperand(1), CarryIn); diff --git a/llvm/test/CodeGen/X86/add-of-carry.ll b/llvm/test/CodeGen/X86/add-of-carry.ll --- a/llvm/test/CodeGen/X86/add-of-carry.ll +++ b/llvm/test/CodeGen/X86/add-of-carry.ll @@ -9,11 +9,9 @@ define i32 @test1(i32 %sum, i32 %x) nounwind readnone ssp { ; CHECK-LABEL: test1: ; CHECK: # %bb.0: -; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx ; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax -; CHECK-NEXT: movl %eax, %edx -; CHECK-NEXT: addl %ecx, %edx -; CHECK-NEXT: adcl %ecx, %eax +; CHECK-NEXT: addl {{[0-9]+}}(%esp), %eax +; CHECK-NEXT: adcl $0, %eax ; CHECK-NEXT: retl %add4 = add i32 %x, %sum %cmp = icmp ult i32 %add4, %x