forked from OSchip/llvm-project
[AVX] Support EXTRACT_SUBVECTOR on x86. This provides a default
implementation of EXTRACT_SUBVECTOR for x86, going through the stack in a similr fashion to how the codegen implements BUILD_VECTOR. Eventually this will get matched to VEXTRACTF128 if AVX is available. llvm-svn: 124292
This commit is contained in:
parent
c41d94eb1a
commit
b6f1611928
|
@ -191,10 +191,10 @@ def SDTVecInsert : SDTypeProfile<1, 3, [ // vector insert
|
|||
]>;
|
||||
|
||||
def SDTSubVecExtract : SDTypeProfile<1, 2, [// subvector extract
|
||||
SDTCisSubVecOfVec<0,1>
|
||||
SDTCisSubVecOfVec<0,1>, SDTCisInt<2>
|
||||
]>;
|
||||
def SDTSubVecInsert : SDTypeProfile<1, 3, [ // subvector insert
|
||||
SDTCisSubVecOfVec<2, 1>, SDTCisSameAs<0,1>
|
||||
SDTCisSubVecOfVec<2, 1>, SDTCisSameAs<0,1>, SDTCisInt<3>
|
||||
]>;
|
||||
|
||||
def SDTPrefetch : SDTypeProfile<0, 3, [ // prefetch
|
||||
|
@ -435,11 +435,17 @@ def scalar_to_vector : SDNode<"ISD::SCALAR_TO_VECTOR", SDTypeProfile<1, 1, []>,
|
|||
[]>;
|
||||
def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT",
|
||||
SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>;
|
||||
def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT",
|
||||
SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>;
|
||||
|
||||
// This operator does not do subvector type checking. The ARM
|
||||
// backend, at least, needs it.
|
||||
def vector_extract_subvec : SDNode<"ISD::EXTRACT_SUBVECTOR",
|
||||
SDTypeProfile<1, 2, [SDTCisInt<2>, SDTCisVec<1>, SDTCisVec<0>]>,
|
||||
[]>;
|
||||
def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT",
|
||||
SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>;
|
||||
|
||||
// This operator does subvector type checking.
|
||||
def extract_subvector : SDNode<"ISD::EXTRACT_SUBVECTOR", SDTSubVecExtract, []>;
|
||||
|
||||
// Nodes for intrinsics, you should use the intrinsic itself and let tblgen use
|
||||
// these internally. Don't reference these directly.
|
||||
|
|
|
@ -625,9 +625,9 @@ void DAGTypeLegalizer::SplitVecRes_CONVERT_RNDSAT(SDNode *N, SDValue &Lo,
|
|||
EVT InNVT = EVT::getVectorVT(*DAG.getContext(), InVT.getVectorElementType(),
|
||||
LoVT.getVectorNumElements());
|
||||
VLo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InNVT, InOp,
|
||||
DAG.getIntPtrConstant(0));
|
||||
DAG.getIntPtrConstant(0));
|
||||
VHi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InNVT, InOp,
|
||||
DAG.getIntPtrConstant(InNVT.getVectorNumElements()));
|
||||
DAG.getIntPtrConstant(InNVT.getVectorNumElements()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2864,11 +2864,30 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT,
|
|||
return getConstant(ShiftedVal.trunc(ElementSize), VT);
|
||||
}
|
||||
break;
|
||||
case ISD::EXTRACT_SUBVECTOR:
|
||||
if (N1.getValueType() == VT) // Trivial extraction.
|
||||
return N1;
|
||||
case ISD::EXTRACT_SUBVECTOR: {
|
||||
SDValue Index = N2;
|
||||
if (VT.isSimple() && N1.getValueType().isSimple()) {
|
||||
assert(VT.isVector() && N1.getValueType().isVector() &&
|
||||
"Extract subvector VTs must be a vectors!");
|
||||
assert(VT.getVectorElementType() == N1.getValueType().getVectorElementType() &&
|
||||
"Extract subvector VTs must have the same element type!");
|
||||
assert(VT.getSimpleVT() <= N1.getValueType().getSimpleVT() &&
|
||||
"Extract subvector must be from larger vector to smaller vector!");
|
||||
|
||||
if (ConstantSDNode *CSD = dyn_cast<ConstantSDNode>(Index.getNode())) {
|
||||
uint64_t Idx = CSD->getZExtValue();
|
||||
assert((VT.getVectorNumElements() + Idx
|
||||
<= N1.getValueType().getVectorNumElements())
|
||||
&& "Extract subvector overflow!");
|
||||
}
|
||||
|
||||
// Trivial extraction.
|
||||
if (VT.getSimpleVT() == N1.getValueType().getSimpleVT())
|
||||
return N1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (N1C) {
|
||||
if (N2C) {
|
||||
|
|
|
@ -5845,6 +5845,17 @@ X86TargetLowering::LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const {
|
|||
DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v4i32,AnyExt));
|
||||
}
|
||||
|
||||
// Lower a node with an EXTRACT_SUBVECTOR opcode. This may result in
|
||||
// a simple subregister reference or explicit instructions to grab
|
||||
// upper bits of a vector.
|
||||
SDValue
|
||||
X86TargetLowering::LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const {
|
||||
if (Subtarget->hasAVX()) {
|
||||
// TODO
|
||||
}
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as
|
||||
// their target countpart wrapped in the X86ISD::Wrapper node. Suppose N is
|
||||
// one of the above mentioned nodes. It has to be wrapped because otherwise
|
||||
|
@ -8693,6 +8704,7 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
|||
case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG);
|
||||
case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG);
|
||||
case ISD::INSERT_VECTOR_ELT: return LowerINSERT_VECTOR_ELT(Op, DAG);
|
||||
case ISD::EXTRACT_SUBVECTOR: return LowerEXTRACT_SUBVECTOR(Op, DAG);
|
||||
case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(Op, DAG);
|
||||
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
|
||||
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
|
||||
|
|
|
@ -741,6 +741,7 @@ namespace llvm {
|
|||
SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerINSERT_VECTOR_ELT_SSE4(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerGlobalAddress(const GlobalValue *GV, DebugLoc dl,
|
||||
|
|
Loading…
Reference in New Issue