summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
diff options
context:
space:
mode:
authorLeonard Chan <leonardchan@google.com>2018-10-22 23:08:40 +0000
committerLeonard Chan <leonardchan@google.com>2018-10-22 23:08:40 +0000
commit0acfc6be384ad769dd3a72d771aa44e5ba6749ad (patch)
tree751f33e1590511cc499c388d07390c1dd5dab76f /llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
parenta0beeffeed3d24cf65ec165141926f7715380eb2 (diff)
downloadbcm5719-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.cpp49
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);
+ }
}
OpenPOWER on IntegriCloud