diff options
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 1c8f6aad21c..43be941e1a4 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -1104,6 +1104,14 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, setOperationAction(ISD::SRA, VT, Custom); } + if (ExperimentalVectorWideningLegalization) { + // These types need custom splitting if their input is a 128-bit vector. + setOperationAction(ISD::SIGN_EXTEND, MVT::v8i64, Custom); + setOperationAction(ISD::SIGN_EXTEND, MVT::v16i32, Custom); + setOperationAction(ISD::ZERO_EXTEND, MVT::v8i64, Custom); + setOperationAction(ISD::ZERO_EXTEND, MVT::v16i32, Custom); + } + setOperationAction(ISD::ROTL, MVT::v8i32, Custom); setOperationAction(ISD::ROTL, MVT::v16i16, Custom); setOperationAction(ISD::ROTL, MVT::v32i8, Custom); @@ -1368,6 +1376,13 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, setOperationAction(ISD::SIGN_EXTEND, MVT::v16i32, Custom); setOperationAction(ISD::SIGN_EXTEND, MVT::v8i64, Custom); + if (ExperimentalVectorWideningLegalization) { + // Need to custom widen this if we don't have AVX512BW. + setOperationAction(ISD::ANY_EXTEND, MVT::v8i8, Custom); + setOperationAction(ISD::ZERO_EXTEND, MVT::v8i8, Custom); + setOperationAction(ISD::SIGN_EXTEND, MVT::v8i8, Custom); + } + for (auto VT : { MVT::v16f32, MVT::v8f64 }) { setOperationAction(ISD::FFLOOR, VT, Legal); setOperationAction(ISD::FCEIL, VT, Legal); @@ -17636,6 +17651,17 @@ static SDValue LowerAVXExtend(SDValue Op, SelectionDAG &DAG, InVT.getVectorElementType() == MVT::i32) && "Unexpected element type"); + // Custom legalize v8i8->v8i64 on CPUs without avx512bw. + if (InVT == MVT::v8i8) { + if (!ExperimentalVectorWideningLegalization || VT != MVT::v8i64) + return SDValue(); + + In = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(Op), + MVT::v16i8, In, DAG.getUNDEF(MVT::v8i8)); + // FIXME: This should be ANY_EXTEND_VECTOR_INREG for ANY_EXTEND input. + return DAG.getNode(ISD::ZERO_EXTEND_VECTOR_INREG, dl, VT, In); + } + if (Subtarget.hasInt256()) return Op; @@ -20089,6 +20115,16 @@ static SDValue LowerSIGN_EXTEND(SDValue Op, const X86Subtarget &Subtarget, InVT.getVectorElementType() == MVT::i32) && "Unexpected element type"); + // Custom legalize v8i8->v8i64 on CPUs without avx512bw. + if (InVT == MVT::v8i8) { + if (!ExperimentalVectorWideningLegalization || VT != MVT::v8i64) + return SDValue(); + + In = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(Op), + MVT::v16i8, In, DAG.getUNDEF(MVT::v8i8)); + return DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, dl, VT, In); + } + if (Subtarget.hasInt256()) return Op; @@ -26307,6 +26343,41 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N, } return; } + case ISD::SIGN_EXTEND: + case ISD::ZERO_EXTEND: { + if (!ExperimentalVectorWideningLegalization) + return; + + EVT VT = N->getValueType(0); + assert((VT == MVT::v16i32 || VT == MVT::v8i64) && "Unexpected VT!"); + SDValue In = N->getOperand(0); + EVT InVT = In.getValueType(); + if (InVT.is128BitVector()) { + // Perform custom splitting instead of the two stage extend we would get + // by default. + EVT LoVT, HiVT; + std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); + assert(isTypeLegal(LoVT) && "Split VT not legal?"); + + bool IsSigned = N->getOpcode() == ISD::SIGN_EXTEND; + + SDValue Lo = getExtendInVec(IsSigned, dl, LoVT, In, DAG); + + // We need to shift the input over by half the number of elements. + unsigned NumElts = InVT.getVectorNumElements(); + unsigned HalfNumElts = NumElts / 2; + SmallVector<int, 16> ShufMask(NumElts, SM_SentinelUndef); + for (unsigned i = 0; i != HalfNumElts; ++i) + ShufMask[i] = i + HalfNumElts; + + SDValue Hi = DAG.getVectorShuffle(InVT, dl, In, In, ShufMask); + Hi = getExtendInVec(IsSigned, dl, HiVT, Hi, DAG); + + SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, Lo, Hi); + Results.push_back(Res); + } + return; + } case ISD::FP_TO_SINT: case ISD::FP_TO_UINT: { bool IsSigned = N->getOpcode() == ISD::FP_TO_SINT; @@ -38715,6 +38786,9 @@ combineToExtendBoolVectorInReg(SDNode *N, SelectionDAG &DAG, static SDValue combineToExtendVectorInReg(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const X86Subtarget &Subtarget) { + if (ExperimentalVectorWideningLegalization) + return SDValue(); + unsigned Opcode = N->getOpcode(); if (Opcode != ISD::SIGN_EXTEND && Opcode != ISD::ZERO_EXTEND) return SDValue(); |

