summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJames Molloy <james.molloy@arm.com>2015-07-16 15:22:46 +0000
committerJames Molloy <james.molloy@arm.com>2015-07-16 15:22:46 +0000
commit7395a8182c7d377cb75e302144d3c21a85f4094f (patch)
tree11a902712960020aa80fc093c04d59f59b0f813c /llvm/lib
parent0e20b8dc9338903faaed3f2326635a40cf9edc19 (diff)
downloadbcm5719-llvm-7395a8182c7d377cb75e302144d3c21a85f4094f.tar.gz
bcm5719-llvm-7395a8182c7d377cb75e302144d3c21a85f4094f.zip
[Codegen] Add intrinsics 'absdiff' and corresponding SDNodes for absolute difference operation
This adds new intrinsics "*absdiff" for absolute difference ops to facilitate efficient code generation for "sum of absolute differences" operation. The patch also contains the introduction of corresponding SDNodes and basic legalization support.Sanity of the generated code is tested on X86. This is 1st of the three patches. Patch by Shahid Asghar-ahmad! llvm-svn: 242409
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp4
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp28
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp2
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp12
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp2
-rw-r--r--llvm/lib/CodeGen/TargetLoweringBase.cpp2
6 files changed, 50 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 9f060a09a0f..511239ce477 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -146,6 +146,10 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS:
Res = PromoteIntRes_AtomicCmpSwap(cast<AtomicSDNode>(N), ResNo);
break;
+ case ISD::UABSDIFF:
+ case ISD::SABSDIFF:
+ Res = PromoteIntRes_SimpleIntBinOp(N);
+ break;
}
// If the result is null then the sub-method took care of registering it.
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
index 83d4ad5ea1f..0f25a610724 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
@@ -105,6 +105,7 @@ class VectorLegalizer {
SDValue ExpandLoad(SDValue Op);
SDValue ExpandStore(SDValue Op);
SDValue ExpandFNEG(SDValue Op);
+ SDValue ExpandABSDIFF(SDValue Op);
/// \brief Implements vector promotion.
///
@@ -326,6 +327,8 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
case ISD::SMAX:
case ISD::UMIN:
case ISD::UMAX:
+ case ISD::UABSDIFF:
+ case ISD::SABSDIFF:
QueryType = Node->getValueType(0);
break;
case ISD::FP_ROUND_INREG:
@@ -708,11 +711,36 @@ SDValue VectorLegalizer::Expand(SDValue Op) {
return ExpandFNEG(Op);
case ISD::SETCC:
return UnrollVSETCC(Op);
+ case ISD::UABSDIFF:
+ case ISD::SABSDIFF:
+ return ExpandABSDIFF(Op);
default:
return DAG.UnrollVectorOp(Op.getNode());
}
}
+SDValue VectorLegalizer::ExpandABSDIFF(SDValue Op) {
+ SDLoc dl(Op);
+ SDValue Tmp1, Tmp2, Tmp3, Tmp4;
+ EVT VT = Op.getValueType();
+ SDNodeFlags Flags;
+ Flags.setNoSignedWrap(Op->getOpcode() == ISD::SABSDIFF);
+
+ Tmp2 = Op.getOperand(0);
+ Tmp3 = Op.getOperand(1);
+ Tmp1 = DAG.getNode(ISD::SUB, dl, VT, Tmp2, Tmp3, &Flags);
+ Tmp2 =
+ DAG.getNode(ISD::SUB, dl, VT, DAG.getConstant(0, dl, VT), Tmp1, &Flags);
+ Tmp4 = DAG.getNode(
+ ISD::SETCC, dl,
+ TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT), Tmp2,
+ DAG.getConstant(0, dl, VT),
+ DAG.getCondCode(Op->getOpcode() == ISD::SABSDIFF ? ISD::SETLT
+ : ISD::SETULT));
+ Tmp1 = DAG.getNode(ISD::VSELECT, dl, VT, Tmp4, Tmp1, Tmp2);
+ return Tmp1;
+}
+
SDValue VectorLegalizer::ExpandSELECT(SDValue Op) {
// Lower a select instruction where the condition is a scalar and the
// operands are vectors. Lower this select to VSELECT and implement it
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 4348ab79f7d..5f9afc9cfc5 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -678,6 +678,8 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
case ISD::SMAX:
case ISD::UMIN:
case ISD::UMAX:
+ case ISD::UABSDIFF:
+ case ISD::SABSDIFF:
SplitVecRes_BinOp(N, Lo, Hi);
break;
case ISD::FMA:
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 5c8db914845..73de6e3cfbd 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4646,6 +4646,18 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
getValue(I.getArgOperand(0)).getValueType(),
getValue(I.getArgOperand(0))));
return nullptr;
+ case Intrinsic::uabsdiff:
+ setValue(&I, DAG.getNode(ISD::UABSDIFF, sdl,
+ getValue(I.getArgOperand(0)).getValueType(),
+ getValue(I.getArgOperand(0)),
+ getValue(I.getArgOperand(1))));
+ return nullptr;
+ case Intrinsic::sabsdiff:
+ setValue(&I, DAG.getNode(ISD::SABSDIFF, sdl,
+ getValue(I.getArgOperand(0)).getValueType(),
+ getValue(I.getArgOperand(0)),
+ getValue(I.getArgOperand(1))));
+ return nullptr;
case Intrinsic::cttz: {
SDValue Arg = getValue(I.getArgOperand(0));
ConstantInt *CI = cast<ConstantInt>(I.getArgOperand(1));
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 5b9b18286fa..8dabddc642b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -225,6 +225,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::SHL_PARTS: return "shl_parts";
case ISD::SRA_PARTS: return "sra_parts";
case ISD::SRL_PARTS: return "srl_parts";
+ case ISD::UABSDIFF: return "uabsdiff";
+ case ISD::SABSDIFF: return "sabsdiff";
// Conversion operators.
case ISD::SIGN_EXTEND: return "sign_extend";
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index 50240bf7046..e6d07f5134b 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -827,6 +827,8 @@ void TargetLoweringBase::initActions() {
setOperationAction(ISD::USUBO, VT, Expand);
setOperationAction(ISD::SMULO, VT, Expand);
setOperationAction(ISD::UMULO, VT, Expand);
+ setOperationAction(ISD::UABSDIFF, VT, Expand);
+ setOperationAction(ISD::SABSDIFF, VT, Expand);
// These library functions default to expand.
setOperationAction(ISD::FROUND, VT, Expand);
OpenPOWER on IntegriCloud