1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[X86] Handle more cases in combineAddOrSubToADCOrSBB.

This adds support for

X + SETAE --> sbb X, -1
X - SETAE --> adc X, -1

Fixes PR45700

Differential Revision: https://reviews.llvm.org/D78984
This commit is contained in:
Craig Topper 2020-04-28 10:24:44 -07:00
parent da04a7f27b
commit 6068fc0c0b
4 changed files with 77 additions and 56 deletions

View File

@ -46168,7 +46168,7 @@ static SDValue combineAddOrSubToADCOrSBB(SDNode *N, SelectionDAG &DAG) {
}
if (CC == X86::COND_A) {
SDValue EFLAGS = Y->getOperand(1);
SDValue EFLAGS = Y.getOperand(1);
// Try to convert COND_A into COND_B in an attempt to facilitate
// materializing "setb reg".
//
@ -46181,13 +46181,44 @@ static SDValue combineAddOrSubToADCOrSBB(SDNode *N, SelectionDAG &DAG) {
SDValue NewSub = DAG.getNode(X86ISD::SUB, SDLoc(EFLAGS),
EFLAGS.getNode()->getVTList(),
EFLAGS.getOperand(1), EFLAGS.getOperand(0));
SDValue NewEFLAGS = SDValue(NewSub.getNode(), EFLAGS.getResNo());
SDValue NewEFLAGS = NewSub.getValue(EFLAGS.getResNo());
return DAG.getNode(IsSub ? X86ISD::SBB : X86ISD::ADC, DL,
DAG.getVTList(VT, MVT::i32), X,
DAG.getConstant(0, DL, VT), NewEFLAGS);
}
}
if (CC == X86::COND_AE) {
// X + SETAE --> sbb X, -1
// X - SETAE --> adc X, -1
return DAG.getNode(IsSub ? X86ISD::ADC : X86ISD::SBB, DL,
DAG.getVTList(VT, MVT::i32), X,
DAG.getConstant(-1, DL, VT), Y.getOperand(1));
}
if (CC == X86::COND_BE) {
// X + SETBE --> sbb X, -1
// X - SETBE --> adc X, -1
SDValue EFLAGS = Y.getOperand(1);
// Try to convert COND_BE into COND_AE in an attempt to facilitate
// materializing "setae reg".
//
// Do not flip "e <= c", where "c" is a constant, because Cmp instruction
// cannot take an immediate as its first operand.
//
if (EFLAGS.getOpcode() == X86ISD::SUB && EFLAGS.getNode()->hasOneUse() &&
EFLAGS.getValueType().isInteger() &&
!isa<ConstantSDNode>(EFLAGS.getOperand(1))) {
SDValue NewSub = DAG.getNode(
X86ISD::SUB, SDLoc(EFLAGS), EFLAGS.getNode()->getVTList(),
EFLAGS.getOperand(1), EFLAGS.getOperand(0));
SDValue NewEFLAGS = NewSub.getValue(EFLAGS.getResNo());
return DAG.getNode(IsSub ? X86ISD::ADC : X86ISD::SBB, DL,
DAG.getVTList(VT, MVT::i32), X,
DAG.getConstant(-1, DL, VT), NewEFLAGS);
}
}
if (CC != X86::COND_E && CC != X86::COND_NE)
return SDValue();

View File

@ -262,10 +262,9 @@ define i32 @ult_zext_add(i32 %0, i32 %1, i32 %2) {
define i32 @ule_zext_add(i32 %0, i32 %1, i32 %2) {
; CHECK-LABEL: ule_zext_add:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpl %edx, %esi
; CHECK-NEXT: setbe %al
; CHECK-NEXT: addl %edi, %eax
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: cmpl %esi, %edx
; CHECK-NEXT: sbbl $-1, %eax
; CHECK-NEXT: retq
%4 = icmp ule i32 %1, %2
%5 = zext i1 %4 to i32
@ -289,10 +288,9 @@ define i32 @ugt_zext_add(i32 %0, i32 %1, i32 %2) {
define i32 @uge_zext_add(i32 %0, i32 %1, i32 %2) {
; CHECK-LABEL: uge_zext_add:
; CHECK: # %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: cmpl %edx, %esi
; CHECK-NEXT: setae %al
; CHECK-NEXT: addl %edi, %eax
; CHECK-NEXT: sbbl $-1, %eax
; CHECK-NEXT: retq
%4 = icmp uge i32 %1, %2
%5 = zext i1 %4 to i32
@ -317,10 +315,8 @@ define i32 @ule_sext_add(i32 %0, i32 %1, i32 %2) {
; CHECK-LABEL: ule_sext_add:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: xorl %ecx, %ecx
; CHECK-NEXT: cmpl %edx, %esi
; CHECK-NEXT: setbe %cl
; CHECK-NEXT: subl %ecx, %eax
; CHECK-NEXT: cmpl %esi, %edx
; CHECK-NEXT: adcl $-1, %eax
; CHECK-NEXT: retq
%4 = icmp ule i32 %1, %2
%5 = sext i1 %4 to i32
@ -345,10 +341,8 @@ define i32 @uge_sext_add(i32 %0, i32 %1, i32 %2) {
; CHECK-LABEL: uge_sext_add:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %edi, %eax
; CHECK-NEXT: xorl %ecx, %ecx
; CHECK-NEXT: cmpl %edx, %esi
; CHECK-NEXT: setae %cl
; CHECK-NEXT: subl %ecx, %eax
; CHECK-NEXT: adcl $-1, %eax
; CHECK-NEXT: retq
%4 = icmp uge i32 %1, %2
%5 = sext i1 %4 to i32

View File

@ -700,43 +700,37 @@ define i64 @test4(i64 %a, i64 %b) nounwind {
; ILP-NEXT: movl $0, %edx
; ILP-NEXT: sbbq %rdx, %rdx
; ILP-NEXT: sbbq %rcx, %rcx
; ILP-NEXT: setae %cl
; ILP-NEXT: movzbl %cl, %ecx
; ILP-NEXT: subq %rcx, %rax
; ILP-NEXT: adcq $-1, %rax
; ILP-NEXT: retq
;
; HYBRID-LABEL: test4:
; HYBRID: # %bb.0:
; HYBRID-NEXT: xorl %eax, %eax
; HYBRID-NEXT: xorl %ecx, %ecx
; HYBRID-NEXT: xorl %edx, %edx
; HYBRID-NEXT: incq %rsi
; HYBRID-NEXT: sete %cl
; HYBRID-NEXT: cmpq %rdi, %rsi
; HYBRID-NEXT: sbbq $0, %rcx
; HYBRID-NEXT: movl $0, %ecx
; HYBRID-NEXT: sbbq %rcx, %rcx
; HYBRID-NEXT: sbbq %rax, %rax
; HYBRID-NEXT: setae %al
; HYBRID-NEXT: movzbl %al, %ecx
; HYBRID-NEXT: sete %dl
; HYBRID-NEXT: movl $2, %eax
; HYBRID-NEXT: subq %rcx, %rax
; HYBRID-NEXT: cmpq %rdi, %rsi
; HYBRID-NEXT: sbbq $0, %rdx
; HYBRID-NEXT: movl $0, %edx
; HYBRID-NEXT: sbbq %rdx, %rdx
; HYBRID-NEXT: sbbq %rcx, %rcx
; HYBRID-NEXT: adcq $-1, %rax
; HYBRID-NEXT: retq
;
; BURR-LABEL: test4:
; BURR: # %bb.0:
; BURR-NEXT: xorl %eax, %eax
; BURR-NEXT: xorl %ecx, %ecx
; BURR-NEXT: xorl %edx, %edx
; BURR-NEXT: incq %rsi
; BURR-NEXT: sete %cl
; BURR-NEXT: cmpq %rdi, %rsi
; BURR-NEXT: sbbq $0, %rcx
; BURR-NEXT: movl $0, %ecx
; BURR-NEXT: sbbq %rcx, %rcx
; BURR-NEXT: sbbq %rax, %rax
; BURR-NEXT: setae %al
; BURR-NEXT: movzbl %al, %ecx
; BURR-NEXT: sete %dl
; BURR-NEXT: movl $2, %eax
; BURR-NEXT: subq %rcx, %rax
; BURR-NEXT: cmpq %rdi, %rsi
; BURR-NEXT: sbbq $0, %rdx
; BURR-NEXT: movl $0, %edx
; BURR-NEXT: sbbq %rdx, %rdx
; BURR-NEXT: sbbq %rcx, %rcx
; BURR-NEXT: adcq $-1, %rax
; BURR-NEXT: retq
;
; SRC-LABEL: test4:
@ -750,10 +744,8 @@ define i64 @test4(i64 %a, i64 %b) nounwind {
; SRC-NEXT: movl $0, %eax
; SRC-NEXT: sbbq %rax, %rax
; SRC-NEXT: sbbq %rcx, %rcx
; SRC-NEXT: setae %al
; SRC-NEXT: movzbl %al, %ecx
; SRC-NEXT: movl $2, %eax
; SRC-NEXT: subq %rcx, %rax
; SRC-NEXT: adcq $-1, %rax
; SRC-NEXT: retq
;
; LIN-LABEL: test4:
@ -768,9 +760,7 @@ define i64 @test4(i64 %a, i64 %b) nounwind {
; LIN-NEXT: movl $0, %edx
; LIN-NEXT: sbbq %rdx, %rdx
; LIN-NEXT: sbbq %rcx, %rcx
; LIN-NEXT: setae %cl
; LIN-NEXT: movzbl %cl, %ecx
; LIN-NEXT: subq %rcx, %rax
; LIN-NEXT: adcq $-1, %rax
; LIN-NEXT: retq
%r = zext i64 %b to i256
%u = add i256 %r, 1

View File

@ -904,29 +904,35 @@ define i32 @test13(i32 %a, i32 %b) nounwind {
}
define i32 @test14(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: test14:
; CHECK: ## %bb.0:
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpl %esi, %edi
; CHECK-NEXT: setae %al
; CHECK-NEXT: negl %eax
; CHECK-NEXT: retq
; GENERIC-LABEL: test14:
; GENERIC: ## %bb.0:
; GENERIC-NEXT: xorl %eax, %eax
; GENERIC-NEXT: cmpl %esi, %edi
; GENERIC-NEXT: adcl $-1, %eax
; GENERIC-NEXT: retq
;
; ATOM-LABEL: test14:
; ATOM: ## %bb.0:
; ATOM-NEXT: xorl %eax, %eax
; ATOM-NEXT: cmpl %esi, %edi
; ATOM-NEXT: adcl $-1, %eax
; ATOM-NEXT: nop
; ATOM-NEXT: nop
; ATOM-NEXT: retq
;
; ATHLON-LABEL: test14:
; ATHLON: ## %bb.0:
; ATHLON-NEXT: movl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: xorl %eax, %eax
; ATHLON-NEXT: cmpl {{[0-9]+}}(%esp), %ecx
; ATHLON-NEXT: setae %al
; ATHLON-NEXT: negl %eax
; ATHLON-NEXT: adcl $-1, %eax
; ATHLON-NEXT: retl
;
; MCU-LABEL: test14:
; MCU: # %bb.0:
; MCU-NEXT: xorl %ecx, %ecx
; MCU-NEXT: cmpl %edx, %eax
; MCU-NEXT: setae %cl
; MCU-NEXT: negl %ecx
; MCU-NEXT: adcl $-1, %ecx
; MCU-NEXT: movl %ecx, %eax
; MCU-NEXT: retl
%c = icmp uge i32 %a, %b