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 @@ -3059,21 +3059,26 @@ // Our goal is to identify A, B, and CarryIn and produce ADDCARRY/SUBCARRY with // a single path for carry/borrow out propagation: static SDValue combineCarryDiamond(SelectionDAG &DAG, const TargetLowering &TLI, - SDValue Carry0, SDValue Carry1, SDNode *N) { - if (Carry0.getResNo() != 1 || Carry1.getResNo() != 1) + SDValue N0, SDValue N1, SDNode *N) { + SDValue Carry0 = getAsCarry(TLI, N0); + if (!Carry0) return SDValue(); + SDValue Carry1 = getAsCarry(TLI, N1); + if (!Carry1) + return SDValue(); + unsigned Opcode = Carry0.getOpcode(); if (Opcode != Carry1.getOpcode()) return SDValue(); if (Opcode != ISD::UADDO && Opcode != ISD::USUBO) return SDValue(); - // Canonicalize the add/sub of A and B as Carry0 and the add/sub of the - // carry/borrow in as Carry1. (The top and middle uaddo nodes respectively in - // the above ASCII art.) - if (Carry1.getOperand(0) != Carry0.getValue(0) && - Carry1.getOperand(1) != Carry0.getValue(0)) + // Canonicalize the add/sub of A and B (the top node in the above ASCII art) + // as Carry0 and the add/sub of the carry in as Carry1 (the middle node). + if (Carry1.getNode()->isOperandOf(Carry0.getNode())) std::swap(Carry0, Carry1); + + // Check if nodes are connected in expected way. if (Carry1.getOperand(0) != Carry0.getValue(0) && Carry1.getOperand(1) != Carry0.getValue(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 @@ -451,12 +451,9 @@ ; CHECK-LABEL: addcarry_hidden_2x64: ; CHECK: # %bb.0: ; CHECK-NEXT: movq %rdi, %rax -; CHECK-NEXT: addq %rcx, %rsi -; CHECK-NEXT: setb %dil ; CHECK-NEXT: addq %rdx, %rax -; CHECK-NEXT: adcq $0, %rsi +; CHECK-NEXT: adcq %rcx, %rsi ; CHECK-NEXT: setb %cl -; CHECK-NEXT: orb %dil, %cl ; CHECK-NEXT: movq %rsi, %rdx ; CHECK-NEXT: retq %t0 = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x0, i64 %y0)