diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index c3b508d0a9a3a..cbb718b0f0d75 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -52972,7 +52972,9 @@ static SDValue combineSub(SDNode *N, SelectionDAG &DAG, return V; // Fold SUB(X,SBB(Y,Z,W)) -> SUB(ADC(X,Z,W),Y) - if (Op1.getOpcode() == X86ISD::SBB && Op1->hasOneUse()) { + // Don't fold to ADC(0,0,W)/SETCC_CARRY pattern which will prevent more folds. + if (Op1.getOpcode() == X86ISD::SBB && Op1->hasOneUse() && + !(X86::isZeroNode(Op0) && X86::isZeroNode(Op1.getOperand(1)))) { SDValue ADC = DAG.getNode(X86ISD::ADC, SDLoc(Op1), Op1->getVTList(), Op0, Op1.getOperand(1), Op1.getOperand(2)); return DAG.getNode(ISD::SUB, SDLoc(N), Op0.getValueType(), ADC.getValue(0), diff --git a/llvm/test/CodeGen/X86/add-sub-bool.ll b/llvm/test/CodeGen/X86/add-sub-bool.ll index 706bd0904ed83..8acde2cfd6b8e 100644 --- a/llvm/test/CodeGen/X86/add-sub-bool.ll +++ b/llvm/test/CodeGen/X86/add-sub-bool.ll @@ -258,23 +258,21 @@ define i32 @test_i32_sub_sub_commute_idx(i32 %x, i32 %y, i32 %z) nounwind { define i32 @test_i32_sub_sum_idx(i32 %x, i32 %y, i32 %z) nounwind { ; X86-LABEL: test_i32_sub_sum_idx: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx -; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx -; X86-NEXT: xorl %eax, %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: addl {{[0-9]+}}(%esp), %eax ; X86-NEXT: btl $30, {{[0-9]+}}(%esp) -; X86-NEXT: sbbl %eax, %eax -; X86-NEXT: andl $1, %eax -; X86-NEXT: subl %ecx, %eax +; X86-NEXT: sbbl $0, %eax +; X86-NEXT: negl %eax ; X86-NEXT: retl ; ; X64-LABEL: test_i32_sub_sum_idx: ; X64: # %bb.0: -; X64-NEXT: addl %esi, %edi -; X64-NEXT: xorl %eax, %eax +; X64-NEXT: # kill: def $esi killed $esi def $rsi +; X64-NEXT: # kill: def $edi killed $edi def $rdi +; X64-NEXT: leal (%rdi,%rsi), %eax ; X64-NEXT: btl $30, %edx -; X64-NEXT: sbbl %eax, %eax -; X64-NEXT: andl $1, %eax -; X64-NEXT: subl %edi, %eax +; X64-NEXT: sbbl $0, %eax +; X64-NEXT: negl %eax ; X64-NEXT: retq %shift = lshr i32 %z, 30 %mask = and i32 %shift, 1 @@ -502,27 +500,23 @@ define i32 @test_i32_sub_sub_commute_var(i32 %x, i32 %y, i32 %z, i32 %w) nounwin define i32 @test_i32_sub_sum_var(i32 %x, i32 %y, i32 %z, i32 %w) nounwind { ; X86-LABEL: test_i32_sub_sum_var: ; X86: # %bb.0: -; X86-NEXT: pushl %esi ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx -; X86-NEXT: movl {{[0-9]+}}(%esp), %esi -; X86-NEXT: addl {{[0-9]+}}(%esp), %esi -; X86-NEXT: xorl %eax, %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: addl {{[0-9]+}}(%esp), %eax ; X86-NEXT: btl %ecx, %edx -; X86-NEXT: sbbl %eax, %eax -; X86-NEXT: andl $1, %eax -; X86-NEXT: subl %esi, %eax -; X86-NEXT: popl %esi +; X86-NEXT: sbbl $0, %eax +; X86-NEXT: negl %eax ; X86-NEXT: retl ; ; X64-LABEL: test_i32_sub_sum_var: ; X64: # %bb.0: -; X64-NEXT: addl %esi, %edi -; X64-NEXT: xorl %eax, %eax +; X64-NEXT: # kill: def $esi killed $esi def $rsi +; X64-NEXT: # kill: def $edi killed $edi def $rdi +; X64-NEXT: leal (%rdi,%rsi), %eax ; X64-NEXT: btl %ecx, %edx -; X64-NEXT: sbbl %eax, %eax -; X64-NEXT: andl $1, %eax -; X64-NEXT: subl %edi, %eax +; X64-NEXT: sbbl $0, %eax +; X64-NEXT: negl %eax ; X64-NEXT: retq %shift = lshr i32 %z, %w %mask = and i32 %shift, 1