Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1961,6 +1961,13 @@ VT.isInteger() && DAG.haveNoCommonBitsSet(N0, N1)) return DAG.getNode(ISD::OR, DL, VT, N0, N1); + // fold (add (xor a, -1), 1) -> (sub 0, a) + if (N0.getOpcode() == ISD::XOR && + isOneConstantOrOneSplatConstant(N1) && + isAllOnesConstantOrAllOnesSplatConstant(N0.getOperand(1))) + return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), + N0.getOperand(0)); + if (SDValue Combined = visitADDLike(N0, N1, N)) return Combined; @@ -2080,6 +2087,13 @@ return CombineTo(N, DAG.getNode(ISD::ADD, DL, VT, N0, N1), DAG.getConstant(0, DL, CarryVT)); + // fold (uaddo (xor a, -1), 1) -> (sub 0, a) + if (N0.getOpcode() == ISD::XOR && + isOneConstantOrOneSplatConstant(N1) && + isAllOnesConstantOrAllOnesSplatConstant(N0.getOperand(1))) + return DAG.getNode(ISD::USUBO, DL, N->getVTList(), + DAG.getConstant(0, DL, VT), N0.getOperand(0)); + if (SDValue Combined = visitUADDOLike(N0, N1, N)) return Combined; Index: test/CodeGen/X86/subcarry.ll =================================================================== --- test/CodeGen/X86/subcarry.ll +++ test/CodeGen/X86/subcarry.ll @@ -6,13 +6,12 @@ define %S @negate(%S* nocapture readonly %this) { ; CHECK-LABEL: negate: ; CHECK: # BB#0: # %entry -; CHECK-NEXT: movq (%rsi), %rax +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: subq (%rsi), %rax ; CHECK-NEXT: movq 8(%rsi), %rcx -; CHECK-NEXT: notq %rax -; CHECK-NEXT: addq $1, %rax +; CHECK-NEXT: movq 16(%rsi), %rdx ; CHECK-NEXT: notq %rcx ; CHECK-NEXT: adcq $0, %rcx -; CHECK-NEXT: movq 16(%rsi), %rdx ; CHECK-NEXT: notq %rdx ; CHECK-NEXT: adcq $0, %rdx ; CHECK-NEXT: movq 24(%rsi), %rsi