OSDN Git Service

[DAGCombiner] Do various combine on uaddo.
authorAmaury Sechet <deadalnix@gmail.com>
Thu, 9 Mar 2017 22:47:00 +0000 (22:47 +0000)
committerAmaury Sechet <deadalnix@gmail.com>
Thu, 9 Mar 2017 22:47:00 +0000 (22:47 +0000)
Summary: This essentially does the same transform as for ADC.

Reviewers: jyknight, nemanjai, mkuper, spatel, RKSimon, zvi, bkramer

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D30417

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297416 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
test/CodeGen/X86/xaluo.ll

index 626dfae..d539bbe 100644 (file)
@@ -235,6 +235,7 @@ namespace {
     SDValue visitADDLike(SDValue N0, SDValue N1, SDNode *LocReference);
     SDValue visitSUB(SDNode *N);
     SDValue visitADDC(SDNode *N);
+    SDValue visitUADDO(SDNode *N);
     SDValue visitSUBC(SDNode *N);
     SDValue visitUSUBO(SDNode *N);
     SDValue visitADDE(SDNode *N);
@@ -1400,6 +1401,7 @@ SDValue DAGCombiner::visit(SDNode *N) {
   case ISD::ADD:                return visitADD(N);
   case ISD::SUB:                return visitSUB(N);
   case ISD::ADDC:               return visitADDC(N);
+  case ISD::UADDO:              return visitUADDO(N);
   case ISD::SUBC:               return visitSUBC(N);
   case ISD::USUBO:              return visitUSUBO(N);
   case ISD::ADDE:               return visitADDE(N);
@@ -1928,6 +1930,39 @@ SDValue DAGCombiner::visitADDC(SDNode *N) {
   return SDValue();
 }
 
+SDValue DAGCombiner::visitUADDO(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 ADD.
+  if (!N->hasAnyUseOfValue(1))
+    return CombineTo(N, DAG.getNode(ISD::ADD, DL, VT, N0, N1),
+                     DAG.getUNDEF(CarryVT));
+
+  // canonicalize constant to RHS.
+  ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
+  ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
+  if (N0C && !N1C)
+    return DAG.getNode(ISD::UADDO, DL, N->getVTList(), N1, N0);
+
+  // fold (uaddo x, 0) -> x + no carry out
+  if (isNullConstant(N1))
+    return CombineTo(N, N0, DAG.getConstant(0, DL, CarryVT));
+
+  // If it cannot overflow, transform into an add.
+  if (DAG.computeOverflowKind(N0, N1) == SelectionDAG::OFK_Never)
+    return CombineTo(N, DAG.getNode(ISD::ADD, DL, VT, N0, N1),
+                     DAG.getConstant(0, DL, CarryVT));
+
+  return SDValue();
+}
+
 SDValue DAGCombiner::visitADDE(SDNode *N) {
   SDValue N0 = N->getOperand(0);
   SDValue N1 = N->getOperand(1);
index 9155350..25fd21d 100644 (file)
@@ -1345,7 +1345,7 @@ define {i64, i1} @uaddoovf(i64 %a, i64 %b) {
 ; SDAG-NEXT:    movzbl %dil, %ecx
 ; SDAG-NEXT:    movzbl %sil, %eax
 ; SDAG-NEXT:    addq %rcx, %rax
-; SDAG-NEXT:    setb %dl
+; SDAG-NEXT:    xorl %edx, %edx
 ; SDAG-NEXT:    retq
 ;
 ; FAST-LABEL: uaddoovf:
@@ -1353,7 +1353,7 @@ define {i64, i1} @uaddoovf(i64 %a, i64 %b) {
 ; FAST-NEXT:    movzbl %dil, %ecx
 ; FAST-NEXT:    movzbl %sil, %eax
 ; FAST-NEXT:    addq %rcx, %rax
-; FAST-NEXT:    setb %dl
+; FAST-NEXT:    xorl %edx, %edx
 ; FAST-NEXT:    retq
 ;
 ; KNL-LABEL: uaddoovf:
@@ -1361,7 +1361,7 @@ define {i64, i1} @uaddoovf(i64 %a, i64 %b) {
 ; KNL-NEXT:    movzbl %dil, %ecx
 ; KNL-NEXT:    movzbl %sil, %eax
 ; KNL-NEXT:    addq %rcx, %rax
-; KNL-NEXT:    setb %dl
+; KNL-NEXT:    xorl %edx, %edx
 ; KNL-NEXT:    retq
   %1 = and i64 %a, 255
   %2 = and i64 %b, 255