[llvm] r372380 - [IntrinsicEmitter] Add overloaded types for SVE intrinsics (Subdivide2 & Subdivide4)
Kerry McLaughlin via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 20 02:48:21 PDT 2019
Author: kmclaughlin
Date: Fri Sep 20 02:48:21 2019
New Revision: 372380
URL: http://llvm.org/viewvc/llvm-project?rev=372380&view=rev
Log:
[IntrinsicEmitter] Add overloaded types for SVE intrinsics (Subdivide2 & Subdivide4)
Summary:
Both match the type of another intrinsic parameter of a vector type, but where each element is subdivided to form a vector with more elements of a smaller type.
Subdivide2Argument allows intrinsics such as the following to be defined:
- declare <vscale x 4 x i32> @llvm.something.nxv4i32(<vscale x 8 x i16>)
Subdivide4Argument allows intrinsics such as:
- declare <vscale x 4 x i32> @llvm.something.nxv4i32(<vscale x 16 x i8>)
Tests are included in follow up patches which add intrinsics using these types.
Reviewers: sdesmalen, SjoerdMeijer, greened, rovka
Reviewed By: sdesmalen
Subscribers: rovka, tschuett, jdoerfert, cfe-commits, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D67549
Modified:
llvm/trunk/include/llvm/IR/DerivedTypes.h
llvm/trunk/include/llvm/IR/Intrinsics.h
llvm/trunk/include/llvm/IR/Intrinsics.td
llvm/trunk/lib/IR/Function.cpp
llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
Modified: llvm/trunk/include/llvm/IR/DerivedTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DerivedTypes.h?rev=372380&r1=372379&r2=372380&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DerivedTypes.h (original)
+++ llvm/trunk/include/llvm/IR/DerivedTypes.h Fri Sep 20 02:48:21 2019
@@ -475,16 +475,42 @@ public:
return VectorType::get(EltTy, VTy->getElementCount());
}
- /// This static method is like getInteger except that the element types are
- /// half as wide as the elements in the input type.
+ // This static method gets a VectorType with the same number of elements as
+ // the input type, and the element type is an integer or float type which
+ // is half as wide as the elements in the input type.
static VectorType *getTruncatedElementVectorType(VectorType *VTy) {
- unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
- assert((EltBits & 1) == 0 &&
- "Cannot truncate vector element with odd bit-width");
- Type *EltTy = IntegerType::get(VTy->getContext(), EltBits / 2);
+ Type *EltTy;
+ if (VTy->getElementType()->isFloatingPointTy()) {
+ switch(VTy->getElementType()->getTypeID()) {
+ case DoubleTyID:
+ EltTy = Type::getFloatTy(VTy->getContext());
+ break;
+ case FloatTyID:
+ EltTy = Type::getHalfTy(VTy->getContext());
+ break;
+ default:
+ llvm_unreachable("Cannot create narrower fp vector element type");
+ }
+ } else {
+ unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
+ assert((EltBits & 1) == 0 &&
+ "Cannot truncate vector element with odd bit-width");
+ EltTy = IntegerType::get(VTy->getContext(), EltBits / 2);
+ }
return VectorType::get(EltTy, VTy->getElementCount());
}
+ // This static method returns a VectorType with a smaller number of elements
+ // of a larger type than the input element type. For example, a <16 x i8>
+ // subdivided twice would return <4 x i32>
+ static VectorType *getSubdividedVectorType(VectorType *VTy, int NumSubdivs) {
+ for (int i = 0; i < NumSubdivs; ++i) {
+ VTy = VectorType::getDoubleElementsVectorType(VTy);
+ VTy = VectorType::getTruncatedElementVectorType(VTy);
+ }
+ return VTy;
+ }
+
/// This static method returns a VectorType with half as many elements as the
/// input type and the same element type.
static VectorType *getHalfElementsVectorType(VectorType *VTy) {
Modified: llvm/trunk/include/llvm/IR/Intrinsics.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.h?rev=372380&r1=372379&r2=372380&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Intrinsics.h (original)
+++ llvm/trunk/include/llvm/IR/Intrinsics.h Fri Sep 20 02:48:21 2019
@@ -100,7 +100,8 @@ namespace Intrinsic {
Integer, Vector, Pointer, Struct,
Argument, ExtendArgument, TruncArgument, HalfVecArgument,
SameVecWidthArgument, PtrToArgument, PtrToElt, VecOfAnyPtrsToElt,
- VecElementArgument, ScalableVecArgument
+ VecElementArgument, ScalableVecArgument, Subdivide2Argument,
+ Subdivide4Argument
} Kind;
union {
@@ -125,14 +126,16 @@ namespace Intrinsic {
assert(Kind == Argument || Kind == ExtendArgument ||
Kind == TruncArgument || Kind == HalfVecArgument ||
Kind == SameVecWidthArgument || Kind == PtrToArgument ||
- Kind == PtrToElt || Kind == VecElementArgument);
+ Kind == PtrToElt || Kind == VecElementArgument ||
+ Kind == Subdivide2Argument || Kind == Subdivide4Argument);
return Argument_Info >> 3;
}
ArgKind getArgumentKind() const {
assert(Kind == Argument || Kind == ExtendArgument ||
Kind == TruncArgument || Kind == HalfVecArgument ||
Kind == SameVecWidthArgument || Kind == PtrToArgument ||
- Kind == VecElementArgument);
+ Kind == VecElementArgument || Kind == Subdivide2Argument ||
+ Kind == Subdivide4Argument);
return (ArgKind)(Argument_Info & 7);
}
Modified: llvm/trunk/include/llvm/IR/Intrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=372380&r1=372379&r2=372380&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Intrinsics.td (original)
+++ llvm/trunk/include/llvm/IR/Intrinsics.td Fri Sep 20 02:48:21 2019
@@ -187,6 +187,12 @@ class LLVMVectorElementType<int num> : L
// vector type, but change the element count to be half as many
class LLVMHalfElementsVectorType<int num> : LLVMMatchType<num>;
+// Match the type of another intrinsic parameter that is expected to be a
+// vector type (i.e. <N x iM>) but with each element subdivided to
+// form a vector with more elements that are smaller than the original.
+class LLVMSubdivide2VectorType<int num> : LLVMMatchType<num>;
+class LLVMSubdivide4VectorType<int num> : LLVMMatchType<num>;
+
def llvm_void_ty : LLVMType<isVoid>;
let isAny = 1 in {
def llvm_any_ty : LLVMType<Any>;
Modified: llvm/trunk/lib/IR/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Function.cpp?rev=372380&r1=372379&r2=372380&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Function.cpp (original)
+++ llvm/trunk/lib/IR/Function.cpp Fri Sep 20 02:48:21 2019
@@ -703,7 +703,9 @@ enum IIT_Info {
IIT_STRUCT8 = 40,
IIT_F128 = 41,
IIT_VEC_ELEMENT = 42,
- IIT_SCALABLE_VEC = 43
+ IIT_SCALABLE_VEC = 43,
+ IIT_SUBDIVIDE2_ARG = 44,
+ IIT_SUBDIVIDE4_ARG = 45
};
static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
@@ -868,6 +870,18 @@ static void DecodeIITType(unsigned &Next
DecodeIITType(NextElt, Infos, OutputTable);
return;
}
+ case IIT_SUBDIVIDE2_ARG: {
+ unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Subdivide2Argument,
+ ArgInfo));
+ return;
+ }
+ case IIT_SUBDIVIDE4_ARG: {
+ unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::Subdivide4Argument,
+ ArgInfo));
+ return;
+ }
case IIT_VEC_ELEMENT: {
unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
OutputTable.push_back(IITDescriptor::get(IITDescriptor::VecElementArgument,
@@ -970,6 +984,14 @@ static Type *DecodeFixedType(ArrayRef<In
assert(ITy->getBitWidth() % 2 == 0);
return IntegerType::get(Context, ITy->getBitWidth() / 2);
}
+ case IITDescriptor::Subdivide2Argument:
+ case IITDescriptor::Subdivide4Argument: {
+ Type *Ty = Tys[D.getArgumentNumber()];
+ VectorType *VTy = dyn_cast<VectorType>(Ty);
+ assert(VTy && "Expected an argument of Vector Type");
+ int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;
+ return VectorType::getSubdividedVectorType(VTy, SubDivs);
+ }
case IITDescriptor::HalfVecArgument:
return VectorType::getHalfElementsVectorType(cast<VectorType>(
Tys[D.getArgumentNumber()]));
@@ -1269,6 +1291,20 @@ static bool matchIntrinsicType(
auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]);
return !ReferenceType || Ty != ReferenceType->getElementType();
}
+ case IITDescriptor::Subdivide2Argument:
+ case IITDescriptor::Subdivide4Argument: {
+ // If this is a forward reference, defer the check for later.
+ if (D.getArgumentNumber() >= ArgTys.size())
+ return IsDeferredCheck || DeferCheck(Ty);
+
+ Type *NewTy = ArgTys[D.getArgumentNumber()];
+ if (auto *VTy = dyn_cast<VectorType>(NewTy)) {
+ int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;
+ NewTy = VectorType::getSubdividedVectorType(VTy, SubDivs);
+ return Ty != NewTy;
+ }
+ return true;
+ }
case IITDescriptor::ScalableVecArgument: {
VectorType *VTy = dyn_cast<VectorType>(Ty);
if (!VTy || !VTy->isScalable())
Modified: llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp?rev=372380&r1=372379&r2=372380&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp Fri Sep 20 02:48:21 2019
@@ -221,7 +221,9 @@ enum IIT_Info {
IIT_STRUCT8 = 40,
IIT_F128 = 41,
IIT_VEC_ELEMENT = 42,
- IIT_SCALABLE_VEC = 43
+ IIT_SCALABLE_VEC = 43,
+ IIT_SUBDIVIDE2_ARG = 44,
+ IIT_SUBDIVIDE4_ARG = 45
};
static void EncodeFixedValueType(MVT::SimpleValueType VT,
@@ -293,6 +295,10 @@ static void EncodeFixedType(Record *R, s
Sig.push_back(IIT_PTR_TO_ELT);
else if (R->isSubClassOf("LLVMVectorElementType"))
Sig.push_back(IIT_VEC_ELEMENT);
+ else if (R->isSubClassOf("LLVMSubdivide2VectorType"))
+ Sig.push_back(IIT_SUBDIVIDE2_ARG);
+ else if (R->isSubClassOf("LLVMSubdivide4VectorType"))
+ Sig.push_back(IIT_SUBDIVIDE4_ARG);
else
Sig.push_back(IIT_ARG);
return Sig.push_back((Number << 3) | 7 /*IITDescriptor::AK_MatchType*/);
More information about the llvm-commits
mailing list