diff options
author | Leonard Chan <leonardchan@google.com> | 2018-10-22 23:08:40 +0000 |
---|---|---|
committer | Leonard Chan <leonardchan@google.com> | 2018-10-22 23:08:40 +0000 |
commit | 0acfc6be384ad769dd3a72d771aa44e5ba6749ad (patch) | |
tree | 751f33e1590511cc499c388d07390c1dd5dab76f /llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | |
parent | a0beeffeed3d24cf65ec165141926f7715380eb2 (diff) | |
download | bcm5719-llvm-0acfc6be384ad769dd3a72d771aa44e5ba6749ad.tar.gz bcm5719-llvm-0acfc6be384ad769dd3a72d771aa44e5ba6749ad.zip |
[Intrinsic] Unigned Saturation Addition Intrinsic
Add an intrinsic that takes 2 integers and perform unsigned saturation
addition on them.
This is a part of implementing fixed point arithmetic in clang where some of
the more complex operations will be implemented as intrinsics.
Differential Revision: https://reviews.llvm.org/D53340
llvm-svn: 344971
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index ceedd06da1d..d31d6344519 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -4681,13 +4681,12 @@ SDValue TargetLowering::lowerCmpEqZeroToCtlzSrl(SDValue Op, return SDValue(); } -SDValue -TargetLowering::getExpandedSignedSaturationAddition(SDNode *Node, - SelectionDAG &DAG) const { - assert(Node->getOpcode() == ISD::SADDSAT && - "Expected method to receive SADDSAT node."); - assert(Node->getNumOperands() == 2 && - "Expected SADDSAT node to have 2 operands."); +SDValue TargetLowering::getExpandedSaturationAddition(SDNode *Node, + SelectionDAG &DAG) const { + unsigned Opcode = Node->getOpcode(); + assert((Opcode == ISD::SADDSAT || Opcode == ISD::UADDSAT) && + "Expected method to receive SADDSAT or UADDSAT node."); + assert(Node->getNumOperands() == 2 && "Expected node to have 2 operands."); SDLoc dl(Node); SDValue LHS = Node->getOperand(0); @@ -4699,27 +4698,33 @@ TargetLowering::getExpandedSignedSaturationAddition(SDNode *Node, "Expected operands to be integers. Vector of int arguments should " "already be unrolled."); assert(LHS.getValueType() == RHS.getValueType() && - "Expected both operands of SADDSAT to be the same type"); + "Expected both operands to be the same type"); + unsigned OverflowOp = Opcode == ISD::SADDSAT ? ISD::SADDO : ISD::UADDO; unsigned BitWidth = LHS.getValueSizeInBits(); EVT ResultType = LHS.getValueType(); EVT BoolVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), ResultType); SDValue Result = - DAG.getNode(ISD::SADDO, dl, DAG.getVTList(ResultType, BoolVT), LHS, RHS); + DAG.getNode(OverflowOp, dl, DAG.getVTList(ResultType, BoolVT), LHS, RHS); SDValue Sum = Result.getValue(0); SDValue Overflow = Result.getValue(1); - - // SatMax -> Overflow && Sum < 0 - // SatMin -> Overflow && Sum > 0 - SDValue Zero = DAG.getConstant(0, dl, LHS.getValueType()); - - SDValue SumNeg = DAG.getSetCC(dl, BoolVT, Sum, Zero, ISD::SETLT); - APInt MinVal = APInt::getSignedMinValue(BitWidth); - APInt MaxVal = APInt::getSignedMaxValue(BitWidth); - SDValue SatMin = DAG.getConstant(MinVal, dl, ResultType); - SDValue SatMax = DAG.getConstant(MaxVal, dl, ResultType); - - Result = DAG.getSelect(dl, ResultType, SumNeg, SatMax, SatMin); - return DAG.getSelect(dl, ResultType, Overflow, Result, Sum); + SDValue Zero = DAG.getConstant(0, dl, ResultType); + + if (Opcode == ISD::SADDSAT) { + // SatMax -> Overflow && Sum < 0 + // SatMin -> Overflow && Sum > 0 + APInt MinVal = APInt::getSignedMinValue(BitWidth); + APInt MaxVal = APInt::getSignedMaxValue(BitWidth); + SDValue SatMin = DAG.getConstant(MinVal, dl, ResultType); + SDValue SatMax = DAG.getConstant(MaxVal, dl, ResultType); + SDValue SumNeg = DAG.getSetCC(dl, BoolVT, Sum, Zero, ISD::SETLT); + Result = DAG.getSelect(dl, ResultType, SumNeg, SatMax, SatMin); + return DAG.getSelect(dl, ResultType, Overflow, Result, Sum); + } else { + // Just need to check overflow for SatMax. + APInt MaxVal = APInt::getMaxValue(BitWidth); + SDValue SatMax = DAG.getConstant(MaxVal, dl, ResultType); + return DAG.getSelect(dl, ResultType, Overflow, SatMax, Sum); + } } |