mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-11 21:45:16 +00:00
[DAGCombine] (add/uaddo X, Carry) -> (addcarry X, 0, Carry)
Summary: This enables further transforms. Depends on D32916 Reviewers: jyknight, nemanjai, mkuper, spatel, RKSimon, zvi, bkramer Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D32925 llvm-svn: 304401
This commit is contained in:
parent
7d95c5e097
commit
6c7366f926
@ -1970,6 +1970,44 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
static SDValue getAsCarry(const TargetLowering &TLI, SDValue V) {
|
||||
bool Masked = false;
|
||||
|
||||
// First, peel away TRUNCATE/ZERO_EXTEND/AND nodes due to legalization.
|
||||
while (true) {
|
||||
if (V.getOpcode() == ISD::TRUNCATE || V.getOpcode() == ISD::ZERO_EXTEND) {
|
||||
V = V.getOperand(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (V.getOpcode() == ISD::AND && isOneConstant(V.getOperand(1))) {
|
||||
Masked = true;
|
||||
V = V.getOperand(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// If this is not a carry, return.
|
||||
if (V.getResNo() != 1)
|
||||
return SDValue();
|
||||
|
||||
if (V.getOpcode() != ISD::ADDCARRY && V.getOpcode() != ISD::SUBCARRY &&
|
||||
V.getOpcode() != ISD::UADDO && V.getOpcode() != ISD::USUBO)
|
||||
return SDValue();
|
||||
|
||||
// If the result is masked, then no matter what kind of bool it is we can
|
||||
// return. If it isn't, then we need to make sure the bool type is either 0 or
|
||||
// 1 and not other values.
|
||||
if (Masked ||
|
||||
TLI.getBooleanContents(V.getValueType()) ==
|
||||
TargetLoweringBase::ZeroOrOneBooleanContent)
|
||||
return V;
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
SDValue DAGCombiner::visitADDLike(SDValue N0, SDValue N1, SDNode *LocReference) {
|
||||
EVT VT = N0.getValueType();
|
||||
SDLoc DL(LocReference);
|
||||
@ -2017,6 +2055,12 @@ SDValue DAGCombiner::visitADDLike(SDValue N0, SDValue N1, SDNode *LocReference)
|
||||
return DAG.getNode(ISD::ADDCARRY, DL, N1->getVTList(),
|
||||
N0, N1.getOperand(0), N1.getOperand(2));
|
||||
|
||||
// (add X, Carry) -> (addcarry X, 0, Carry)
|
||||
if (SDValue Carry = getAsCarry(TLI, N1))
|
||||
return DAG.getNode(ISD::ADDCARRY, DL,
|
||||
DAG.getVTList(VT, Carry.getValueType()), N0,
|
||||
DAG.getConstant(0, DL, VT), Carry);
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
@ -2100,6 +2144,11 @@ SDValue DAGCombiner::visitUADDOLike(SDValue N0, SDValue N1, SDNode *N) {
|
||||
N1.getOperand(2));
|
||||
}
|
||||
|
||||
// (uaddo X, Carry) -> (addcarry X, 0, Carry)
|
||||
if (SDValue Carry = getAsCarry(TLI, N1))
|
||||
return DAG.getNode(ISD::ADDCARRY, SDLoc(N), N->getVTList(), N0,
|
||||
DAG.getConstant(0, SDLoc(N), N0.getValueType()), Carry);
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
|
@ -9,9 +9,11 @@
|
||||
define i32 @test1(i32 %sum, i32 %x) nounwind readnone ssp {
|
||||
; CHECK-LABEL: test1:
|
||||
; CHECK: # BB#0:
|
||||
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; CHECK-NEXT: addl {{[0-9]+}}(%esp), %eax
|
||||
; CHECK-NEXT: adcl $0, %eax
|
||||
; CHECK-NEXT: movl %eax, %edx
|
||||
; CHECK-NEXT: addl %ecx, %edx
|
||||
; CHECK-NEXT: adcl %ecx, %eax
|
||||
; CHECK-NEXT: retl
|
||||
%add4 = add i32 %x, %sum
|
||||
%cmp = icmp ult i32 %add4, %x
|
||||
|
@ -190,9 +190,9 @@ entry:
|
||||
define i64 @shiftadd(i64 %a, i64 %b, i64 %c, i64 %d) {
|
||||
; CHECK-LABEL: shiftadd:
|
||||
; CHECK: # BB#0: # %entry
|
||||
; CHECK-NEXT: leaq (%rdx,%rcx), %rax
|
||||
; CHECK-NEXT: addq %rsi, %rdi
|
||||
; CHECK-NEXT: adcq $0, %rax
|
||||
; CHECK-NEXT: adcq %rcx, %rdx
|
||||
; CHECK-NEXT: movq %rdx, %rax
|
||||
; CHECK-NEXT: retq
|
||||
entry:
|
||||
%0 = zext i64 %a to i128
|
||||
|
Loading…
Reference in New Issue
Block a user