diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -53951,6 +53951,14 @@ Op1.getOperand(0), Op1.getOperand(2)); } + // Fold SUB(SBB(X,0,W), Y) -> SBB(X,Y,W) + if (Op0.getOpcode() == X86ISD::SBB && Op0->hasOneUse() && + X86::isZeroNode(Op0.getOperand(1))) { + assert(!Op0->hasAnyUseOfValue(1) && "Overflow bit in use"); + return DAG.getNode(X86ISD::SBB, SDLoc(Op1), Op0->getVTList(), + Op0.getOperand(0), Op1, Op0.getOperand(2)); + } + // Fold SUB(X,SBB(Y,Z,W)) -> SUB(ADC(X,Z,W),Y) // Don't fold to ADC(0,0,W)/SETCC_CARRY pattern which will prevent more folds. if (Op1.getOpcode() == X86ISD::SBB && Op1->hasOneUse() && diff --git a/llvm/test/CodeGen/X86/pr57576.ll b/llvm/test/CodeGen/X86/pr57576.ll --- a/llvm/test/CodeGen/X86/pr57576.ll +++ b/llvm/test/CodeGen/X86/pr57576.ll @@ -6,8 +6,7 @@ ; CHECK: # %bb.0: ; CHECK-NEXT: movq %rdi, %rax ; CHECK-NEXT: subq %rdx, %rax -; CHECK-NEXT: sbbq $0, %rsi -; CHECK-NEXT: subq %rcx, %rsi +; CHECK-NEXT: sbbq %rcx, %rsi ; CHECK-NEXT: movq %rsi, %rdx ; CHECK-NEXT: retq %5 = zext i64 %1 to i128