Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -7872,6 +7872,18 @@ 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) && + (!LegalOperations || TLI.isOperationLegal(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,8 +28,7 @@ ; CHECK-LABEL: b: ; CHECK: # BB#0: # %entry ; CHECK-NEXT: addq %rdx, %rsi -; CHECK-NEXT: sbbq %rax, %rax -; CHECK-NEXT: subl %eax, %ecx +; CHECK-NEXT: adcl $0, %ecx ; CHECK-NEXT: movl %ecx, (%rdi) ; CHECK-NEXT: retq entry: @@ -48,8 +47,7 @@ ; CHECK-LABEL: c: ; CHECK: # BB#0: # %entry ; CHECK-NEXT: addq %rdx, %rsi -; CHECK-NEXT: sbbq %rax, %rax -; CHECK-NEXT: subl %eax, %ecx +; CHECK-NEXT: adcw $0, %cx ; CHECK-NEXT: movw %cx, (%rdi) ; CHECK-NEXT: retq entry: @@ -68,8 +66,7 @@ ; CHECK-LABEL: d: ; CHECK: # BB#0: # %entry ; CHECK-NEXT: addq %rdx, %rsi -; CHECK-NEXT: sbbq %rax, %rax -; CHECK-NEXT: subl %eax, %ecx +; CHECK-NEXT: adcb $0, %cl ; CHECK-NEXT: movb %cl, (%rdi) ; CHECK-NEXT: retq entry: @@ -164,9 +161,8 @@ ; CHECK-NEXT: adcq $0, %rdx ; CHECK-NEXT: movq %rax, (%rdi) ; CHECK-NEXT: addq 8(%rdi), %rdx -; CHECK-NEXT: sbbq %rax, %rax ; CHECK-NEXT: movq %rdx, 8(%rdi) -; CHECK-NEXT: subl %eax, 16(%rdi) +; CHECK-NEXT: adcl $0, 16(%rdi) ; CHECK-NEXT: retq entry: %0 = zext i64 %arg.a to i128