summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2018-10-28 13:07:25 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2018-10-28 13:07:25 +0000
commit9b77f0c291922518d61f56f55d43efa8130366e4 (patch)
treedea5d84597fd4ef3d229ff1750e6039e3d6605b3 /llvm/lib
parent5b30571753cef75c86c6bc11983a5a4e56d5c771 (diff)
downloadbcm5719-llvm-9b77f0c291922518d61f56f55d43efa8130366e4.tar.gz
bcm5719-llvm-9b77f0c291922518d61f56f55d43efa8130366e4.zip
[VectorLegalizer] Enable TargetLowering::expandFP_TO_UINT support.
Add vector support to TargetLowering::expandFP_TO_UINT. This exposes an issue in X86TargetLowering::LowerVSELECT which was assuming that the select mask was the same width as the LHS/RHS ops - as long as the result is a sign splat we can easily sext/trunk this. llvm-svn: 345473
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp19
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp5
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp28
3 files changed, 41 insertions, 11 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
index 6554d5a27b2..122a9856ade 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
@@ -86,9 +86,10 @@ class VectorLegalizer {
/// operations to legalize them.
SDValue Expand(SDValue Op);
- /// Implements expansion for FNEG; falls back to UnrollVectorOp if
- /// FSUB isn't legal.
- ///
+ /// Implements expansion for FP_TO_UINT; falls back to UnrollVectorOp if
+ /// FP_TO_SINT isn't legal.
+ SDValue ExpandFP_TO_UINT(SDValue Op);
+
/// Implements expansion for UINT_TO_FLOAT; falls back to UnrollVectorOp if
/// SINT_TO_FLOAT and SHR on vectors isn't legal.
SDValue ExpandUINT_TO_FLOAT(SDValue Op);
@@ -709,6 +710,8 @@ SDValue VectorLegalizer::Expand(SDValue Op) {
return ExpandVSELECT(Op);
case ISD::SELECT:
return ExpandSELECT(Op);
+ case ISD::FP_TO_UINT:
+ return ExpandFP_TO_UINT(Op);
case ISD::UINT_TO_FP:
return ExpandUINT_TO_FLOAT(Op);
case ISD::FNEG:
@@ -1018,6 +1021,16 @@ SDValue VectorLegalizer::ExpandVSELECT(SDValue Op) {
return DAG.getNode(ISD::BITCAST, DL, Op.getValueType(), Val);
}
+SDValue VectorLegalizer::ExpandFP_TO_UINT(SDValue Op) {
+ // Attempt to expand using TargetLowering.
+ SDValue Result;
+ if (TLI.expandFP_TO_UINT(Op.getNode(), Result, DAG))
+ return Result;
+
+ // Otherwise go ahead and unroll.
+ return DAG.UnrollVectorOp(Op.getNode());
+}
+
SDValue VectorLegalizer::ExpandUINT_TO_FLOAT(SDValue Op) {
EVT VT = Op.getOperand(0).getValueType();
SDLoc DL(Op);
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index d6e7590b8fc..cf6910f4d76 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -4147,6 +4147,11 @@ bool TargetLowering::expandFP_TO_UINT(SDNode *Node, SDValue &Result,
EVT SetCCVT =
getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), SrcVT);
+ // Only expand vector types if we have the appropriate vector bit operations.
+ if (DstVT.isVector() && (!isOperationLegalOrCustom(ISD::FP_TO_SINT, DstVT) ||
+ !isOperationLegalOrCustomOrPromote(ISD::XOR, SrcVT)))
+ return false;
+
// Expand based on maximum range of FP_TO_SINT:
// True = fp_to_sint(Src)
// False = 0x8000000000000000 + fp_to_sint(Src - 0x8000000000000000)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index c2ca88911d2..060b36c868e 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -15698,7 +15698,9 @@ SDValue X86TargetLowering::LowerVSELECT(SDValue Op, SelectionDAG &DAG) const {
// If this VSELECT has a vector if i1 as a mask, it will be directly matched
// with patterns on the mask registers on AVX-512.
- if (Cond.getScalarValueSizeInBits() == 1)
+ MVT CondVT = Cond.getSimpleValueType();
+ unsigned CondEltSize = Cond.getScalarValueSizeInBits();
+ if (CondEltSize == 1)
return Op;
// Variable blends are only legal from SSE4.1 onward.
@@ -15707,24 +15709,34 @@ SDValue X86TargetLowering::LowerVSELECT(SDValue Op, SelectionDAG &DAG) const {
SDLoc dl(Op);
MVT VT = Op.getSimpleValueType();
+ unsigned EltSize = VT.getScalarSizeInBits();
+ unsigned NumElts = VT.getVectorNumElements();
// If the VSELECT is on a 512-bit type, we have to convert a non-i1 condition
// into an i1 condition so that we can use the mask-based 512-bit blend
// instructions.
if (VT.getSizeInBits() == 512) {
- // The vNi1 condition case should be handled above as it can be trivially
- // lowered.
- assert(Cond.getScalarValueSizeInBits() == VT.getScalarSizeInBits() &&
- "Should have a size-matched integer condition!");
// Build a mask by testing the condition against zero.
- MVT MaskVT = MVT::getVectorVT(MVT::i1, VT.getVectorNumElements());
+ MVT MaskVT = MVT::getVectorVT(MVT::i1, NumElts);
SDValue Mask = DAG.getSetCC(dl, MaskVT, Cond,
- getZeroVector(VT, Subtarget, DAG, dl),
+ getZeroVector(CondVT, Subtarget, DAG, dl),
ISD::SETNE);
// Now return a new VSELECT using the mask.
return DAG.getSelect(dl, VT, Mask, LHS, RHS);
}
+ // SEXT/TRUNC cases where the mask doesn't match the destination size.
+ if (CondEltSize != EltSize) {
+ // If we don't have a sign splat, rely on the expansion.
+ if (CondEltSize != DAG.ComputeNumSignBits(Cond))
+ return SDValue();
+
+ MVT NewCondSVT = MVT::getIntegerVT(EltSize);
+ MVT NewCondVT = MVT::getVectorVT(NewCondSVT, NumElts);
+ Cond = DAG.getSExtOrTrunc(Cond, dl, NewCondVT);
+ return DAG.getNode(ISD::VSELECT, dl, VT, Cond, LHS, RHS);
+ }
+
// Only some types will be legal on some subtargets. If we can emit a legal
// VSELECT-matching blend, return Op, and but if we need to expand, return
// a null value.
@@ -15743,7 +15755,7 @@ SDValue X86TargetLowering::LowerVSELECT(SDValue Op, SelectionDAG &DAG) const {
case MVT::v8i16:
case MVT::v16i16: {
// Bitcast everything to the vXi8 type and use a vXi8 vselect.
- MVT CastVT = MVT::getVectorVT(MVT::i8, VT.getVectorNumElements() * 2);
+ MVT CastVT = MVT::getVectorVT(MVT::i8, NumElts * 2);
Cond = DAG.getBitcast(CastVT, Cond);
LHS = DAG.getBitcast(CastVT, LHS);
RHS = DAG.getBitcast(CastVT, RHS);
OpenPOWER on IntegriCloud