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 @@ -3061,6 +3061,17 @@ if (SDValue Combined = visitADDCARRYLike(N1, N0, CarryIn, N)) return Combined; + // We want to avoid useless duplication. + // TODO: This is done automatically for binary operations. As ADDCARRY is + // not a binary operation, this is not really possible to leverage this + // existing mechanism for it. However, if more operations require the same + // deduplication logic, then it may be worth generalize. + SDValue Ops[] = {N1, N0, CarryIn}; + SDNode *CSENode = + DAG.getNodeIfExists(ISD::ADDCARRY, N->getVTList(), Ops, N->getFlags()); + if (CSENode) + return SDValue(CSENode, 0); + 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 @@ -1397,13 +1397,10 @@ define { i64, i64 } @addcarry_commutative_1(i64 %x0, i64 %x1, i64 %y0, i64 %y1) nounwind { ; CHECK-LABEL: addcarry_commutative_1: ; CHECK: # %bb.0: -; CHECK-NEXT: movq %rdi, %rax -; CHECK-NEXT: addq %rdx, %rax ; CHECK-NEXT: movq %rsi, %rax -; CHECK-NEXT: adcq %rcx, %rax ; CHECK-NEXT: addq %rdx, %rdi -; CHECK-NEXT: adcq %rcx, %rsi -; CHECK-NEXT: movq %rsi, %rdx +; CHECK-NEXT: adcq %rcx, %rax +; CHECK-NEXT: movq %rax, %rdx ; CHECK-NEXT: retq %z0 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x0, i64 %y0) %k0 = extractvalue { i64, i1 } %z0, 1 @@ -1424,13 +1421,10 @@ define { i64, i64 } @addcarry_commutative_2(i64 %x0, i64 %x1, i64 %y0, i64 %y1) nounwind { ; CHECK-LABEL: addcarry_commutative_2: ; CHECK: # %bb.0: -; CHECK-NEXT: movq %rdi, %rax -; CHECK-NEXT: addq %rdx, %rax ; CHECK-NEXT: movq %rsi, %rax -; CHECK-NEXT: adcq %rcx, %rax ; CHECK-NEXT: addq %rdx, %rdi -; CHECK-NEXT: adcq %rcx, %rsi -; CHECK-NEXT: movq %rsi, %rdx +; CHECK-NEXT: adcq %rcx, %rax +; CHECK-NEXT: movq %rax, %rdx ; CHECK-NEXT: retq %z0 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x0, i64 %y0) %k0 = extractvalue { i64, i1 } %z0, 1