Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -7866,6 +7866,19 @@ SimplifyDemandedBits(SDValue(N, 0))) return SDValue(N, 0); + // (trunc adde(X, Y, Carry)) -> (adde trunc(X), trunc(Y), Carry) + // When the adde's carry is not used. + if (N0.getOpcode() == ISD::ADDE && + N0.hasOneUse() && + !N0.getNode()->hasAnyUseOfValue(1) && + TLI.isOperationLegalOrCustom(ISD::ADDE, VT)) { + SDLoc SL(N); + auto X = DAG.getNode(ISD::TRUNCATE, SL, VT, N0.getOperand(0)); + auto Y = DAG.getNode(ISD::TRUNCATE, SL, VT, N0.getOperand(1)); + return DAG.getNode(ISD::ADDE, SL, DAG.getVTList(VT, MVT::Glue), + X, Y, N0.getOperand(2)); + } + return SDValue(); } Index: test/CodeGen/X86/adde-carry.ll =================================================================== --- test/CodeGen/X86/adde-carry.ll +++ test/CodeGen/X86/adde-carry.ll @@ -28,10 +28,8 @@ ; CHECK-LABEL: b: ; CHECK: # BB#0: # %entry ; CHECK-NEXT: addq %rdx, %rsi -; CHECK-NEXT: sbbq %rax, %rax -; CHECK-NEXT: andl $1, %eax -; CHECK-NEXT: addl %ecx, %eax -; CHECK-NEXT: movl %eax, (%rdi) +; CHECK-NEXT: adcl $0, %ecx +; CHECK-NEXT: movl %ecx, (%rdi) ; CHECK-NEXT: retq entry: %0 = zext i64 %a to i128 @@ -49,10 +47,8 @@ ; CHECK-LABEL: c: ; CHECK: # BB#0: # %entry ; CHECK-NEXT: addq %rdx, %rsi -; CHECK-NEXT: sbbq %rax, %rax -; CHECK-NEXT: andl $1, %eax -; CHECK-NEXT: addl %ecx, %eax -; CHECK-NEXT: movw %ax, (%rdi) +; CHECK-NEXT: adcl $0, %ecx +; CHECK-NEXT: movw %cx, (%rdi) ; CHECK-NEXT: retq entry: %0 = zext i64 %a to i128 @@ -70,10 +66,8 @@ ; CHECK-LABEL: d: ; CHECK: # BB#0: # %entry ; CHECK-NEXT: addq %rdx, %rsi -; CHECK-NEXT: sbbq %rax, %rax -; CHECK-NEXT: andl $1, %eax -; CHECK-NEXT: addl %ecx, %eax -; CHECK-NEXT: movb %al, (%rdi) +; CHECK-NEXT: adcl $0, %ecx +; CHECK-NEXT: movb %cl, (%rdi) ; CHECK-NEXT: retq entry: %0 = zext i64 %a to i128 @@ -168,9 +162,9 @@ ; CHECK-NEXT: adcq $0, %rdx ; CHECK-NEXT: movq %rax, (%rdi) ; CHECK-NEXT: addq 8(%rdi), %rdx -; CHECK-NEXT: sbbq %rax, %rax -; CHECK-NEXT: andl $1, %eax ; CHECK-NEXT: movq %rdx, 8(%rdi) +; CHECK-NEXT: sbbl %eax, %eax +; CHECK-NEXT: andl $1, %eax ; CHECK-NEXT: addl %eax, 16(%rdi) ; CHECK-NEXT: retq entry: