From 095ffad7c607cab1c6e2230c5fb453ab8112311a Mon Sep 17 00:00:00 2001 From: Amaury Sechet Date: Sun, 5 Feb 2017 14:22:20 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294125 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 20 ++++++++++++++------ test/CodeGen/X86/adde-carry.ll | 18 +++++++----------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index aad07d8ae3c..8028eb3567e 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -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); diff --git a/test/CodeGen/X86/adde-carry.ll b/test/CodeGen/X86/adde-carry.ll index 0eae984525b..e111f683dd3 100644 --- a/test/CodeGen/X86/adde-carry.ll +++ b/test/CodeGen/X86/adde-carry.ll @@ -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 -- 2.50.1