diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -15982,6 +15982,57 @@ """""""""" The argument to this intrinsic must be a vector of floating-point values. +'``llvm.vector.insert``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" +This is an overloaded intrinsic. + +:: + + declare <4 x float> @llvm.vector.insert.v4f32(<4 x float> %subvec, <4 x float> %vec, i64 %idx) + declare <2 x double> @llvm.vector.insert.v2f64(<2 x double> %subvec, <2 x double> %vec, i64 %idx) + +Overview: +""""""""" + +The '``llvm.vector.insert.*``' intrinsics insert a subvector into another vector +at a given index. The return type matches the type of the vector we insert into. + + +Arguments: +"""""""""" + +The ``subvec`` is the vector that will be inserted. +The ``vec`` is the vector which ``subvec`` will be inserted into. +The ``idx`` is the index of ``vec`` where ``subvec`` will be inserted. + +'``llvm.vector.extract``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" +This is an overloaded intrinsic. + +:: + + declare <4 x float> @llvm.vector.extract.v4f32(<4 x float> %vec, i64 %idx) + declare <2 x double> @llvm.vector.extract.v2f64(<2 x double> %vec, i64 %idx) + +Overview: +""""""""" + +The '``llvm.vector.extract.*``' intrinsics extract a subvector from another +vector starting from a given index. The return type must be explicitly +specified. + +Arguments: +"""""""""" + +The ``vec`` is the vector from which we will extract a subvector. +The ``idx`` specifies the start index within ``vec`` of our subvector. + Matrix Intrinsics ----------------- diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -1625,6 +1625,15 @@ //===---------- Intrinsics to query properties of scalable vectors --------===// def int_vscale : DefaultAttrsIntrinsic<[llvm_anyint_ty], [], [IntrNoMem]>; +//===---------- Intrinsics to perform subvector insertion/extraction ------===// +def int_vector_insert : DefaultAttrsIntrinsic<[llvm_anyvector_ty], + [llvm_anyvector_ty, LLVMMatchType<0>, llvm_i64_ty], + [IntrNoMem]>; + +def int_vector_extract : DefaultAttrsIntrinsic<[llvm_anyvector_ty], + [llvm_anyvector_ty, llvm_i64_ty], + [IntrNoMem]>; + //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6892,6 +6892,31 @@ SetCC)); return; } + case Intrinsic::vector_insert: { + auto DL = getCurSDLoc(); + + SDValue SubVec = getValue(I.getOperand(0)); + SDValue Vec = getValue(I.getOperand(1)); + SDValue Index = getValue(I.getOperand(2)); + EVT ResultVT = Vec.getValueType(); + setValue(&I, DAG.getNode(ISD::INSERT_SUBVECTOR, DL, ResultVT, Vec, SubVec, + Index)); + return; + } + case Intrinsic::vector_extract: { + auto DL = getCurSDLoc(); + + SDValue Vec = getValue(I.getOperand(0)); + SDValue Index = getValue(I.getOperand(1)); + + Type *ElementTy = I.getOperand(0)->getType()->getScalarType(); + unsigned VecWidth = + Vec.getValueType().getVectorElementCount().getKnownMinValue(); + EVT ResultVT = EVT::getEVT(FixedVectorType::get(ElementTy, VecWidth)); + + setValue(&I, DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ResultVT, Vec, Index)); + return; + } } }