aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
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/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
parent0e20b8dc9338903faaed3f2326635a40cf9edc19 (diff)
downloadllvm-7395a8182c7d377cb75e302144d3c21a85f4094f.zip
llvm-7395a8182c7d377cb75e302144d3c21a85f4094f.tar.gz
llvm-7395a8182c7d377cb75e302144d3c21a85f4094f.tar.bz2
[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/CodeGen/SelectionDAG/LegalizeVectorOps.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp28
1 files changed, 28 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
index 83d4ad5..0f25a61 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