forked from OSchip/llvm-project
[DAGCombiner] Leverage add's commutativity
Summary: This avoid the need to duplicate all pattern and actually end up exposing some opportunity to optimize existing pattern that did not exists in both directions on an existing test case. Reviewers: mkuper, spatel, bkramer, RKSimon, zvi Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D29541 llvm-svn: 294125
This commit is contained in:
parent
c3ac566754
commit
143902c29f
|
@ -232,6 +232,7 @@ namespace {
|
|||
SDValue visitTokenFactor(SDNode *N);
|
||||
SDValue visitMERGE_VALUES(SDNode *N);
|
||||
SDValue visitADD(SDNode *N);
|
||||
SDValue visitADDLike(SDValue N0, SDValue N1, SDNode *LocReference);
|
||||
SDValue visitSUB(SDNode *N);
|
||||
SDValue visitADDC(SDNode *N);
|
||||
SDValue visitSUBC(SDNode *N);
|
||||
|
@ -1782,6 +1783,19 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
|
|||
VT.isInteger() && DAG.haveNoCommonBitsSet(N0, N1))
|
||||
return DAG.getNode(ISD::OR, DL, VT, N0, N1);
|
||||
|
||||
if (SDValue Combined = visitADDLike(N0, N1, N))
|
||||
return Combined;
|
||||
|
||||
if (SDValue Combined = visitADDLike(N1, N0, N))
|
||||
return Combined;
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
SDValue DAGCombiner::visitADDLike(SDValue N0, SDValue N1, SDNode *LocReference) {
|
||||
EVT VT = N0.getValueType();
|
||||
SDLoc DL(LocReference);
|
||||
|
||||
// fold (add x, shl(0 - y, n)) -> sub(x, shl(y, n))
|
||||
if (N1.getOpcode() == ISD::SHL && N1.getOperand(0).getOpcode() == ISD::SUB &&
|
||||
isNullConstantOrNullSplatConstant(N1.getOperand(0).getOperand(0)))
|
||||
|
@ -1789,12 +1803,6 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
|
|||
DAG.getNode(ISD::SHL, DL, VT,
|
||||
N1.getOperand(0).getOperand(1),
|
||||
N1.getOperand(1)));
|
||||
if (N0.getOpcode() == ISD::SHL && N0.getOperand(0).getOpcode() == ISD::SUB &&
|
||||
isNullConstantOrNullSplatConstant(N0.getOperand(0).getOperand(0)))
|
||||
return DAG.getNode(ISD::SUB, DL, VT, N1,
|
||||
DAG.getNode(ISD::SHL, DL, VT,
|
||||
N0.getOperand(0).getOperand(1),
|
||||
N0.getOperand(1)));
|
||||
|
||||
if (N1.getOpcode() == ISD::AND) {
|
||||
SDValue AndOp0 = N1.getOperand(0);
|
||||
|
|
|
@ -29,9 +29,8 @@ define void @b(i32* nocapture %r, i64 %a, i64 %b, i32 %c) nounwind {
|
|||
; CHECK: # BB#0: # %entry
|
||||
; CHECK-NEXT: addq %rdx, %rsi
|
||||
; CHECK-NEXT: sbbq %rax, %rax
|
||||
; CHECK-NEXT: andl $1, %eax
|
||||
; CHECK-NEXT: addl %ecx, %eax
|
||||
; CHECK-NEXT: movl %eax, (%rdi)
|
||||
; CHECK-NEXT: subl %eax, %ecx
|
||||
; CHECK-NEXT: movl %ecx, (%rdi)
|
||||
; CHECK-NEXT: retq
|
||||
entry:
|
||||
%0 = zext i64 %a to i128
|
||||
|
@ -50,9 +49,8 @@ define void @c(i16* nocapture %r, i64 %a, i64 %b, i16 %c) nounwind {
|
|||
; CHECK: # BB#0: # %entry
|
||||
; CHECK-NEXT: addq %rdx, %rsi
|
||||
; CHECK-NEXT: sbbq %rax, %rax
|
||||
; CHECK-NEXT: andl $1, %eax
|
||||
; CHECK-NEXT: addl %ecx, %eax
|
||||
; CHECK-NEXT: movw %ax, (%rdi)
|
||||
; CHECK-NEXT: subl %eax, %ecx
|
||||
; CHECK-NEXT: movw %cx, (%rdi)
|
||||
; CHECK-NEXT: retq
|
||||
entry:
|
||||
%0 = zext i64 %a to i128
|
||||
|
@ -71,9 +69,8 @@ define void @d(i8* nocapture %r, i64 %a, i64 %b, i8 %c) nounwind {
|
|||
; CHECK: # BB#0: # %entry
|
||||
; CHECK-NEXT: addq %rdx, %rsi
|
||||
; CHECK-NEXT: sbbq %rax, %rax
|
||||
; CHECK-NEXT: andl $1, %eax
|
||||
; CHECK-NEXT: addl %ecx, %eax
|
||||
; CHECK-NEXT: movb %al, (%rdi)
|
||||
; CHECK-NEXT: subl %eax, %ecx
|
||||
; CHECK-NEXT: movb %cl, (%rdi)
|
||||
; CHECK-NEXT: retq
|
||||
entry:
|
||||
%0 = zext i64 %a to i128
|
||||
|
@ -169,9 +166,8 @@ define void @muladd(%accumulator* nocapture %this, i64 %arg.a, i64 %arg.b) {
|
|||
; CHECK-NEXT: movq %rax, (%rdi)
|
||||
; CHECK-NEXT: addq 8(%rdi), %rdx
|
||||
; CHECK-NEXT: sbbq %rax, %rax
|
||||
; CHECK-NEXT: andl $1, %eax
|
||||
; CHECK-NEXT: movq %rdx, 8(%rdi)
|
||||
; CHECK-NEXT: addl %eax, 16(%rdi)
|
||||
; CHECK-NEXT: subl %eax, 16(%rdi)
|
||||
; CHECK-NEXT: retq
|
||||
entry:
|
||||
%0 = zext i64 %arg.a to i128
|
||||
|
|
Loading…
Reference in New Issue