summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmaury Sechet <deadalnix@gmail.com>2017-03-09 19:28:00 +0000
committerAmaury Sechet <deadalnix@gmail.com>2017-03-09 19:28:00 +0000
commit10425de0632a602aa6f8e132128b5a48d822691b (patch)
treebf320b5cf502d029285835255073cf4307964776
parenteef294c961bb1794b285edec3a7d98b40aed9434 (diff)
downloadbcm5719-llvm-10425de0632a602aa6f8e132128b5a48d822691b.tar.gz
bcm5719-llvm-10425de0632a602aa6f8e132128b5a48d822691b.zip
[DAGCombiner] Do various combine on usubo.
Summary: This essentially does the same transform as for SUBC. Reviewers: jyknight, nemanjai, mkuper, spatel, RKSimon, zvi, bkramer Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D30437 llvm-svn: 297404
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp34
-rw-r--r--llvm/test/CodeGen/X86/xaluo.ll38
2 files changed, 43 insertions, 29 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 046c9e9520c..626dfaea957 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -236,6 +236,7 @@ namespace {
SDValue visitSUB(SDNode *N);
SDValue visitADDC(SDNode *N);
SDValue visitSUBC(SDNode *N);
+ SDValue visitUSUBO(SDNode *N);
SDValue visitADDE(SDNode *N);
SDValue visitSUBE(SDNode *N);
SDValue visitMUL(SDNode *N);
@@ -1400,6 +1401,7 @@ SDValue DAGCombiner::visit(SDNode *N) {
case ISD::SUB: return visitSUB(N);
case ISD::ADDC: return visitADDC(N);
case ISD::SUBC: return visitSUBC(N);
+ case ISD::USUBO: return visitUSUBO(N);
case ISD::ADDE: return visitADDE(N);
case ISD::SUBE: return visitSUBE(N);
case ISD::MUL: return visitMUL(N);
@@ -2133,6 +2135,38 @@ SDValue DAGCombiner::visitSUBC(SDNode *N) {
return SDValue();
}
+SDValue DAGCombiner::visitUSUBO(SDNode *N) {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ EVT VT = N0.getValueType();
+ if (VT.isVector())
+ return SDValue();
+
+ EVT CarryVT = N->getValueType(1);
+ SDLoc DL(N);
+
+ // If the flag result is dead, turn this into an SUB.
+ if (!N->hasAnyUseOfValue(1))
+ return CombineTo(N, DAG.getNode(ISD::SUB, DL, VT, N0, N1),
+ DAG.getUNDEF(CarryVT));
+
+ // fold (usubo x, x) -> 0 + no borrow
+ if (N0 == N1)
+ return CombineTo(N, DAG.getConstant(0, DL, VT),
+ DAG.getConstant(0, DL, CarryVT));
+
+ // fold (usubo x, 0) -> x + no borrow
+ if (isNullConstant(N1))
+ return CombineTo(N, N0, DAG.getConstant(0, DL, CarryVT));
+
+ // Canonicalize (usubo -1, x) -> ~x, i.e. (xor x, -1) + no borrow
+ if (isAllOnesConstant(N0))
+ return CombineTo(N, DAG.getNode(ISD::XOR, DL, VT, N1, N0),
+ DAG.getConstant(0, DL, CarryVT));
+
+ return SDValue();
+}
+
SDValue DAGCombiner::visitSUBE(SDNode *N) {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
diff --git a/llvm/test/CodeGen/X86/xaluo.ll b/llvm/test/CodeGen/X86/xaluo.ll
index 5ee30673dbc..9155350e65d 100644
--- a/llvm/test/CodeGen/X86/xaluo.ll
+++ b/llvm/test/CodeGen/X86/xaluo.ll
@@ -1372,43 +1372,23 @@ define {i64, i1} @uaddoovf(i64 %a, i64 %b) {
define {i64, i1} @usuboovf(i64 %a, i64 %b) {
; SDAG-LABEL: usuboovf:
; SDAG: ## BB#0:
-; SDAG-NEXT: subq %rdi, %rdi
-; SDAG-NEXT: sbbb %r8b, %r8b
-; SDAG-NEXT: movq $-1, %rax
-; SDAG-NEXT: subq %rsi, %rax
-; SDAG-NEXT: sbbb %cl, %cl
-; SDAG-NEXT: subq %rdi, %rax
-; SDAG-NEXT: sbbb %dl, %dl
-; SDAG-NEXT: orb %cl, %dl
-; SDAG-NEXT: orb %r8b, %dl
-; SDAG-NEXT: andb $1, %dl
+; SDAG-NEXT: notq %rsi
+; SDAG-NEXT: xorl %edx, %edx
+; SDAG-NEXT: movq %rsi, %rax
; SDAG-NEXT: retq
;
; FAST-LABEL: usuboovf:
; FAST: ## BB#0:
-; FAST-NEXT: subq %rdi, %rdi
-; FAST-NEXT: sbbb %r8b, %r8b
-; FAST-NEXT: movq $-1, %rax
-; FAST-NEXT: subq %rsi, %rax
-; FAST-NEXT: sbbb %cl, %cl
-; FAST-NEXT: subq %rdi, %rax
-; FAST-NEXT: sbbb %dl, %dl
-; FAST-NEXT: orb %cl, %dl
-; FAST-NEXT: orb %r8b, %dl
-; FAST-NEXT: andb $1, %dl
+; FAST-NEXT: notq %rsi
+; FAST-NEXT: xorl %edx, %edx
+; FAST-NEXT: movq %rsi, %rax
; FAST-NEXT: retq
;
; KNL-LABEL: usuboovf:
; KNL: ## BB#0:
-; KNL-NEXT: subq %rdi, %rdi
-; KNL-NEXT: sbbb %dl, %dl
-; KNL-NEXT: movq $-1, %rax
-; KNL-NEXT: subq %rsi, %rax
-; KNL-NEXT: sbbb %cl, %cl
-; KNL-NEXT: orb %dl, %cl
-; KNL-NEXT: subq %rdi, %rax
-; KNL-NEXT: sbbb %dl, %dl
-; KNL-NEXT: orb %cl, %dl
+; KNL-NEXT: notq %rsi
+; KNL-NEXT: xorl %edx, %edx
+; KNL-NEXT: movq %rsi, %rax
; KNL-NEXT: retq
%t0 = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 %a)
%v0 = extractvalue {i64, i1} %t0, 0
OpenPOWER on IntegriCloud