if (SDValue V = combineToHorizontalAddSub(N, DAG, Subtarget))
return V;
+ // Fold SUB(X,SBB(Y,Z,W)) -> SUB(ADC(X,Z,W),Y)
+ if (Op1.getOpcode() == X86ISD::SBB && Op1->hasOneUse()) {
+ 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),
+ Op1.getOperand(0));
+ }
+
return combineAddOrSubToADCOrSBB(N, DAG);
}
; X86-LABEL: test_i32_sub_sub_idx:
; X86: # %bb.0:
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: btl $16, {{[0-9]+}}(%esp)
-; X86-NEXT: sbbl $0, %ecx
-; X86-NEXT: subl %ecx, %eax
+; X86-NEXT: adcl $0, %eax
+; X86-NEXT: subl {{[0-9]+}}(%esp), %eax
; X86-NEXT: retl
;
; X64-LABEL: test_i32_sub_sub_idx:
; X64: # %bb.0:
; X64-NEXT: movl %edi, %eax
; X64-NEXT: btl $16, %edx
-; X64-NEXT: sbbl $0, %esi
+; X64-NEXT: adcl $0, %eax
; X64-NEXT: subl %esi, %eax
; X64-NEXT: retq
%shift = lshr i32 %z, 16
define i32 @test_i32_sub_sub_var(i32 %x, i32 %y, i32 %z, i32 %w) nounwind {
; X86-LABEL: test_i32_sub_sub_var:
; X86: # %bb.0:
-; X86-NEXT: pushl %esi
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
-; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
-; X86-NEXT: btl %edx, %esi
-; X86-NEXT: sbbl $0, %ecx
-; X86-NEXT: subl %ecx, %eax
-; X86-NEXT: popl %esi
+; X86-NEXT: btl %ecx, %edx
+; X86-NEXT: adcl $0, %eax
+; X86-NEXT: subl {{[0-9]+}}(%esp), %eax
; X86-NEXT: retl
;
; X64-LABEL: test_i32_sub_sub_var:
; X64: # %bb.0:
; X64-NEXT: movl %edi, %eax
; X64-NEXT: btl %ecx, %edx
-; X64-NEXT: sbbl $0, %esi
+; X64-NEXT: adcl $0, %eax
; X64-NEXT: subl %esi, %eax
; X64-NEXT: retq
%shift = lshr i32 %z, %w