forked from OSchip/llvm-project
[X86] Don't fold SUB(X,SBB(0,0,W)) -> SUB(ADC(0,0,W),Y)
This will further fold to a AND(SETCC_CARRY(),1) pattern which tends to prevent further folds.
This commit is contained in:
parent
58dda03f7c
commit
b6e2832fc2
|
@ -52972,7 +52972,9 @@ static SDValue combineSub(SDNode *N, SelectionDAG &DAG,
|
||||||
return V;
|
return V;
|
||||||
|
|
||||||
// Fold SUB(X,SBB(Y,Z,W)) -> SUB(ADC(X,Z,W),Y)
|
// 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,
|
SDValue ADC = DAG.getNode(X86ISD::ADC, SDLoc(Op1), Op1->getVTList(), Op0,
|
||||||
Op1.getOperand(1), Op1.getOperand(2));
|
Op1.getOperand(1), Op1.getOperand(2));
|
||||||
return DAG.getNode(ISD::SUB, SDLoc(N), Op0.getValueType(), ADC.getValue(0),
|
return DAG.getNode(ISD::SUB, SDLoc(N), Op0.getValueType(), ADC.getValue(0),
|
||||||
|
|
|
@ -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 {
|
define i32 @test_i32_sub_sum_idx(i32 %x, i32 %y, i32 %z) nounwind {
|
||||||
; X86-LABEL: test_i32_sub_sum_idx:
|
; X86-LABEL: test_i32_sub_sum_idx:
|
||||||
; X86: # %bb.0:
|
; X86: # %bb.0:
|
||||||
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||||
; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx
|
; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
|
||||||
; X86-NEXT: xorl %eax, %eax
|
|
||||||
; X86-NEXT: btl $30, {{[0-9]+}}(%esp)
|
; X86-NEXT: btl $30, {{[0-9]+}}(%esp)
|
||||||
; X86-NEXT: sbbl %eax, %eax
|
; X86-NEXT: sbbl $0, %eax
|
||||||
; X86-NEXT: andl $1, %eax
|
; X86-NEXT: negl %eax
|
||||||
; X86-NEXT: subl %ecx, %eax
|
|
||||||
; X86-NEXT: retl
|
; X86-NEXT: retl
|
||||||
;
|
;
|
||||||
; X64-LABEL: test_i32_sub_sum_idx:
|
; X64-LABEL: test_i32_sub_sum_idx:
|
||||||
; X64: # %bb.0:
|
; X64: # %bb.0:
|
||||||
; X64-NEXT: addl %esi, %edi
|
; X64-NEXT: # kill: def $esi killed $esi def $rsi
|
||||||
; X64-NEXT: xorl %eax, %eax
|
; X64-NEXT: # kill: def $edi killed $edi def $rdi
|
||||||
|
; X64-NEXT: leal (%rdi,%rsi), %eax
|
||||||
; X64-NEXT: btl $30, %edx
|
; X64-NEXT: btl $30, %edx
|
||||||
; X64-NEXT: sbbl %eax, %eax
|
; X64-NEXT: sbbl $0, %eax
|
||||||
; X64-NEXT: andl $1, %eax
|
; X64-NEXT: negl %eax
|
||||||
; X64-NEXT: subl %edi, %eax
|
|
||||||
; X64-NEXT: retq
|
; X64-NEXT: retq
|
||||||
%shift = lshr i32 %z, 30
|
%shift = lshr i32 %z, 30
|
||||||
%mask = and i32 %shift, 1
|
%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 {
|
define i32 @test_i32_sub_sum_var(i32 %x, i32 %y, i32 %z, i32 %w) nounwind {
|
||||||
; X86-LABEL: test_i32_sub_sum_var:
|
; X86-LABEL: test_i32_sub_sum_var:
|
||||||
; X86: # %bb.0:
|
; X86: # %bb.0:
|
||||||
; X86-NEXT: pushl %esi
|
|
||||||
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||||
; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
|
; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
|
||||||
; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
|
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||||
; X86-NEXT: addl {{[0-9]+}}(%esp), %esi
|
; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
|
||||||
; X86-NEXT: xorl %eax, %eax
|
|
||||||
; X86-NEXT: btl %ecx, %edx
|
; X86-NEXT: btl %ecx, %edx
|
||||||
; X86-NEXT: sbbl %eax, %eax
|
; X86-NEXT: sbbl $0, %eax
|
||||||
; X86-NEXT: andl $1, %eax
|
; X86-NEXT: negl %eax
|
||||||
; X86-NEXT: subl %esi, %eax
|
|
||||||
; X86-NEXT: popl %esi
|
|
||||||
; X86-NEXT: retl
|
; X86-NEXT: retl
|
||||||
;
|
;
|
||||||
; X64-LABEL: test_i32_sub_sum_var:
|
; X64-LABEL: test_i32_sub_sum_var:
|
||||||
; X64: # %bb.0:
|
; X64: # %bb.0:
|
||||||
; X64-NEXT: addl %esi, %edi
|
; X64-NEXT: # kill: def $esi killed $esi def $rsi
|
||||||
; X64-NEXT: xorl %eax, %eax
|
; X64-NEXT: # kill: def $edi killed $edi def $rdi
|
||||||
|
; X64-NEXT: leal (%rdi,%rsi), %eax
|
||||||
; X64-NEXT: btl %ecx, %edx
|
; X64-NEXT: btl %ecx, %edx
|
||||||
; X64-NEXT: sbbl %eax, %eax
|
; X64-NEXT: sbbl $0, %eax
|
||||||
; X64-NEXT: andl $1, %eax
|
; X64-NEXT: negl %eax
|
||||||
; X64-NEXT: subl %edi, %eax
|
|
||||||
; X64-NEXT: retq
|
; X64-NEXT: retq
|
||||||
%shift = lshr i32 %z, %w
|
%shift = lshr i32 %z, %w
|
||||||
%mask = and i32 %shift, 1
|
%mask = and i32 %shift, 1
|
||||||
|
|
Loading…
Reference in New Issue