Cleanup of the [SU]ADDO type legalization code. Patch by Duncan!

"It simplifies the type legalization part a bit, and produces better code by
teaching SelectionDAG about the extra bits in an i8 SADDO/UADDO node.  In
essence, I spontaneously decided that on x86 this i8 boolean result would be
either 0 or 1, and on other platforms 0/1 or 0/-1, depending on whether the
platform likes it's boolean zero extended or sign extended."


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59864 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index cd4524e..179329b 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -99,8 +99,8 @@
   case ISD::UDIV:
   case ISD::UREM:        Result = PromoteIntRes_UDIV(N); break;
 
-  case ISD::SADDO:       Result = PromoteIntRes_SADDO(N, ResNo); break;
-  case ISD::UADDO:       Result = PromoteIntRes_UADDO(N, ResNo); break;
+  case ISD::SADDO:
+  case ISD::UADDO:       Result = PromoteIntRes_XADDO(N, ResNo); break;
 
   case ISD::ATOMIC_LOAD_ADD_8:
   case ISD::ATOMIC_LOAD_SUB_8:
@@ -518,26 +518,20 @@
   return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
 }
 
-SDValue DAGTypeLegalizer::PromoteIntRes_XADDO(SDNode *N, unsigned ResNo,
-                                              ISD::NodeType NTy) {
-  MVT NewVT = TLI.getTypeToTransformTo(SDValue(N, ResNo).getValueType());
-  assert(isTypeLegal(NewVT) && "Illegal XADDO type!");
+SDValue DAGTypeLegalizer::PromoteIntRes_XADDO(SDNode *N, unsigned ResNo) {
+  assert(ResNo == 1 && "Only boolean result promotion currently supported!");
 
-  MVT ValueVTs[] = { N->getOperand(0).getValueType(), NewVT };
+  // Simply change the return type of the boolean result.
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1));
+  MVT ValueVTs[] = { N->getValueType(0), NVT };
   SDValue Ops[] = { N->getOperand(0), N->getOperand(1) };
+  SDValue Res = DAG.getNode(N->getOpcode(), DAG.getVTList(ValueVTs, 2), Ops, 2);
 
-  SDValue Res = DAG.getNode(NTy, DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2);
-  ReplaceValueWith(SDValue(N, 0), SDValue(Res.getNode(), 0));
-  ReplaceValueWith(SDValue(N, 1), SDValue(Res.getNode(), 1));
-  return Res;
-}
+  // Modified the sum result - switch anything that used the old sum to use
+  // the new one.
+  ReplaceValueWith(SDValue(N, 0), Res);
 
-SDValue DAGTypeLegalizer::PromoteIntRes_SADDO(SDNode *N, unsigned ResNo) {
-  return PromoteIntRes_XADDO(N, ResNo, ISD::SADDO);
-}
-
-SDValue DAGTypeLegalizer::PromoteIntRes_UADDO(SDNode *N, unsigned ResNo) {
-  return PromoteIntRes_XADDO(N, ResNo, ISD::UADDO);
+  return SDValue(Res.getNode(), 1);
 }
 
 SDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) {
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index e9af5f5..f75fa77 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -268,11 +268,9 @@
   SDValue PromoteIntRes_SRL(SDNode *N);
   SDValue PromoteIntRes_TRUNCATE(SDNode *N);
   SDValue PromoteIntRes_UDIV(SDNode *N);
-  SDValue PromoteIntRes_XADDO(SDNode *N, unsigned ResNo, ISD::NodeType NTy);
-  SDValue PromoteIntRes_SADDO(SDNode *N, unsigned ResNo);
-  SDValue PromoteIntRes_UADDO(SDNode *N, unsigned ResNo);
   SDValue PromoteIntRes_UNDEF(SDNode *N);
   SDValue PromoteIntRes_VAARG(SDNode *N);
+  SDValue PromoteIntRes_XADDO(SDNode *N, unsigned ResNo);
 
   // Integer Operand Promotion.
   bool PromoteIntegerOperand(SDNode *N, unsigned OperandNo);
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 02159de..7d64b24 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1491,6 +1491,11 @@
     KnownOne &= KnownOne2;
     KnownZero &= KnownZero2;
     return;
+  case ISD::SADDO:
+  case ISD::UADDO:
+    if (Op.getResNo() != 1)
+      return;
+    // The boolean result conforms to getSetCCResultContents.  Fall through.
   case ISD::SETCC:
     // If we know the result of a setcc has the top bits zero, use this info.
     if (TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult &&
@@ -1893,7 +1898,12 @@
     if (Tmp == 1) return 1;  // Early out.
     Tmp2 = ComputeNumSignBits(Op.getOperand(2), Depth+1);
     return std::min(Tmp, Tmp2);
-    
+
+  case ISD::SADDO:
+  case ISD::UADDO:
+    if (Op.getResNo() != 1)
+      break;
+    // The boolean result conforms to getSetCCResultContents.  Fall through.
   case ISD::SETCC:
     // If setcc returns 0/-1, all bits are sign bits.
     if (TLI.getSetCCResultContents() ==