From: Bill Wendling Date: Tue, 25 Nov 2008 08:12:19 +0000 (+0000) Subject: Hacker's Delight says, "Signed integer overflow of addition occurs if and only X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8;p=oota-llvm.git 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." git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60014 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 972e4ae8c28..5a6332c1cef 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/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 };