summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2008-11-25 08:12:19 +0000
committerBill Wendling <isanbard@gmail.com>2008-11-25 08:12:19 +0000
commit4498b47677c304daa824e00b643ab938b2fb30de (patch)
tree18b50769faea984ac55853e46282963f2cfbf609 /llvm/lib
parentf3e95505c59613f48f11efc830c5811cb2115418 (diff)
downloadbcm5719-llvm-4498b47677c304daa824e00b643ab938b2fb30de.tar.gz
bcm5719-llvm-4498b47677c304daa824e00b643ab938b2fb30de.zip
Hacker's Delight says, "Signed integer overflow of addition occurs if and only
if the operands have the same sign and the sum has sign opposite to that of the operands." llvm-svn: 60014
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp52
1 files changed, 48 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 972e4ae8c28..5a6332c1cef 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -4170,7 +4170,53 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
break;
}
- case ISD::SADDO:
+ case ISD::SADDO: {
+ MVT VT = Node->getValueType(0);
+ switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
+ default: assert(0 && "This action not supported for this op yet!");
+ case TargetLowering::Custom:
+ Result = TLI.LowerOperation(Op, DAG);
+ if (Result.getNode()) break;
+ // FALLTHROUGH
+ case TargetLowering::Legal: {
+ SDValue LHS = LegalizeOp(Node->getOperand(0));
+ SDValue RHS = LegalizeOp(Node->getOperand(1));
+
+ SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS);
+ MVT SType = Node->getValueType(0);
+ MVT OType = Node->getValueType(1);
+
+ SDValue Zero = DAG.getConstant(0, OType);
+
+ SDValue LHSPos = DAG.getSetCC(OType, LHS, Zero, ISD::SETGE);
+ SDValue RHSPos = DAG.getSetCC(OType, RHS, Zero, ISD::SETGE);
+ SDValue And1 = DAG.getNode(ISD::AND, OType, LHSPos, RHSPos);
+
+ And1 = DAG.getNode(ISD::AND, OType, And1,
+ DAG.getSetCC(OType, Sum, Zero, ISD::SETLT));
+
+ SDValue LHSNeg = DAG.getSetCC(OType, LHS, Zero, ISD::SETLT);
+ SDValue RHSNeg = DAG.getSetCC(OType, RHS, Zero, ISD::SETLT);
+ SDValue And2 = DAG.getNode(ISD::AND, OType, LHSNeg, RHSNeg);
+
+ And2 = DAG.getNode(ISD::AND, OType, And2,
+ DAG.getSetCC(OType, Sum, Zero, ISD::SETGE));
+
+ SDValue Cmp = DAG.getNode(ISD::OR, OType, And1, And2);
+
+ MVT ValueVTs[] = { LHS.getValueType(), OType };
+ SDValue Ops[] = { Sum, Cmp };
+
+ Result = DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2);
+ SDNode *RNode = Result.getNode();
+ DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0));
+ DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), SDValue(RNode, 1));
+ break;
+ }
+ }
+
+ break;
+ }
case ISD::UADDO: {
MVT VT = Node->getValueType(0);
switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
@@ -4185,9 +4231,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
SDValue Sum = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS);
MVT OType = Node->getValueType(1);
- SDValue Cmp = DAG.getSetCC(OType, Sum, LHS,
- (Node->getOpcode() == ISD::SADDO) ?
- ISD::SETLT : ISD::SETULT);
+ SDValue Cmp = DAG.getSetCC(OType, Sum, LHS, ISD::SETULT);
MVT ValueVTs[] = { LHS.getValueType(), OType };
SDValue Ops[] = { Sum, Cmp };
OpenPOWER on IntegriCloud