summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2019-02-26 11:27:53 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2019-02-26 11:27:53 +0000
commit810fa04ac7e367ed1aa736f2c54d980bc6fc09f1 (patch)
tree768fbe18dd07cfa04df8f55bd0358663294cb933 /llvm/lib/CodeGen
parent8335fd1923c1b7d9772dcc0e70a7d51f3773ecc0 (diff)
downloadbcm5719-llvm-810fa04ac7e367ed1aa736f2c54d980bc6fc09f1.tar.gz
bcm5719-llvm-810fa04ac7e367ed1aa736f2c54d980bc6fc09f1.zip
[LegalizeDAG] Expand SADDO/SSUBO using SADDSAT/SSUBSAT (PR37763)
If SADDSAT/SSUBSAT are legal, then we can expand SADDO/SSUBO by performing a ADD/SUB and a SADDO/SSUBO and then compare the results. I looked at doing this for UADDO/USUBO as well but as we don't have to do as many range comparisons I didn't see any/much benefit. Differential Revision: https://reviews.llvm.org/D58637 llvm-svn: 354866
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp22
1 files changed, 17 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 4ee0b933b9e..0e5ba3453c1 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -3261,13 +3261,25 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
case ISD::SSUBO: {
SDValue LHS = Node->getOperand(0);
SDValue RHS = Node->getOperand(1);
- SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ?
- ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
- LHS, RHS);
+ bool IsAdd = Node->getOpcode() == ISD::SADDO;
+
+ SDValue Sum = DAG.getNode(IsAdd ? ISD::ADD : ISD::SUB, dl,
+ LHS.getValueType(), LHS, RHS);
Results.push_back(Sum);
+
EVT ResultType = Node->getValueType(1);
EVT OType = getSetCCResultType(Node->getValueType(0));
+ // If SADDSAT/SSUBSAT is legal, compare results to detect overflow.
+ unsigned OpcSat = IsAdd ? ISD::SADDSAT : ISD::SSUBSAT;
+ if (TLI.isOperationLegalOrCustom(OpcSat, LHS.getValueType())) {
+ SDValue Sat = DAG.getNode(OpcSat, dl, LHS.getValueType(), LHS, RHS);
+ SDValue SetCC = DAG.getSetCC(dl, OType, Sum, Sat, ISD::SETNE);
+ Results.push_back(
+ DAG.getBoolExtOrTrunc(SetCC, dl, ResultType, ResultType));
+ break;
+ }
+
SDValue Zero = DAG.getConstant(0, dl, LHS.getValueType());
// LHSSign -> LHS >= 0
@@ -3281,8 +3293,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
SDValue LHSSign = DAG.getSetCC(dl, OType, LHS, Zero, ISD::SETGE);
SDValue RHSSign = DAG.getSetCC(dl, OType, RHS, Zero, ISD::SETGE);
SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign,
- Node->getOpcode() == ISD::SADDO ?
- ISD::SETEQ : ISD::SETNE);
+ IsAdd ? ISD::SETEQ : ISD::SETNE);
SDValue SumSign = DAG.getSetCC(dl, OType, Sum, Zero, ISD::SETGE);
SDValue SumSignNE = DAG.getSetCC(dl, OType, LHSSign, SumSign, ISD::SETNE);
@@ -3296,6 +3307,7 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
SDValue LHS = Node->getOperand(0);
SDValue RHS = Node->getOperand(1);
bool IsAdd = Node->getOpcode() == ISD::UADDO;
+
// If ADD/SUBCARRY is legal, use that instead.
unsigned OpcCarry = IsAdd ? ISD::ADDCARRY : ISD::SUBCARRY;
if (TLI.isOperationLegalOrCustom(OpcCarry, Node->getValueType(0))) {
OpenPOWER on IntegriCloud