Index: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp @@ -40566,6 +40566,15 @@ Flags); } + // Fold SBB(SUB(X,Y),0,Carry) -> SBB(X,Y,Carry) + // iff the flag result is dead. + SDValue Op0 = N->getOperand(0); + SDValue Op1 = N->getOperand(1); + if (Op0.getOpcode() == ISD::SUB && isNullConstant(Op1) && + !N->hasAnyUseOfValue(1)) + return DAG.getNode(X86ISD::SBB, SDLoc(N), N->getVTList(), Op0.getOperand(0), + Op0.getOperand(1), N->getOperand(2)); + return SDValue(); } Index: llvm/trunk/test/CodeGen/X86/combine-sbb.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/combine-sbb.ll +++ llvm/trunk/test/CodeGen/X86/combine-sbb.ll @@ -13,11 +13,10 @@ ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx ; X86-NEXT: movl (%ecx), %esi ; X86-NEXT: movl 4(%ecx), %ecx -; X86-NEXT: subl 4(%edx), %ecx ; X86-NEXT: subl (%edx), %esi -; X86-NEXT: sbbl $0, %ecx -; X86-NEXT: movl %esi, (%eax) +; X86-NEXT: sbbl 4(%edx), %ecx ; X86-NEXT: movl %ecx, 4(%eax) +; X86-NEXT: movl %esi, (%eax) ; X86-NEXT: popl %esi ; X86-NEXT: retl $4 ; @@ -26,11 +25,10 @@ ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: movl (%rsi), %ecx ; X64-NEXT: movl 4(%rsi), %esi -; X64-NEXT: subl 4(%rdx), %esi ; X64-NEXT: subl (%rdx), %ecx -; X64-NEXT: sbbl $0, %esi -; X64-NEXT: movl %ecx, (%rdi) +; X64-NEXT: sbbl 4(%rdx), %esi ; X64-NEXT: movl %esi, 4(%rdi) +; X64-NEXT: movl %ecx, (%rdi) ; X64-NEXT: retq top: %3 = bitcast %WideUInt32* %1 to i32* @@ -94,11 +92,10 @@ ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: movq (%rsi), %rcx ; X64-NEXT: movq 8(%rsi), %rsi -; X64-NEXT: subq 8(%rdx), %rsi ; X64-NEXT: subq (%rdx), %rcx -; X64-NEXT: sbbq $0, %rsi -; X64-NEXT: movq %rcx, (%rdi) +; X64-NEXT: sbbq 8(%rdx), %rsi ; X64-NEXT: movq %rsi, 8(%rdi) +; X64-NEXT: movq %rcx, (%rdi) ; X64-NEXT: retq top: %3 = bitcast %WideUInt64* %1 to i64*