diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-10-28 13:07:25 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-10-28 13:07:25 +0000 |
commit | 9b77f0c291922518d61f56f55d43efa8130366e4 (patch) | |
tree | dea5d84597fd4ef3d229ff1750e6039e3d6605b3 /llvm/lib | |
parent | 5b30571753cef75c86c6bc11983a5a4e56d5c771 (diff) | |
download | bcm5719-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.cpp | 19 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 28 |
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); |