[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:
Amaury Sechet 2017-02-05 14:22:20 +00:00
parent c3ac566754
commit 143902c29f
2 changed files with 21 additions and 17 deletions

View File

@ -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);

View File

@ -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