From 7c3e057ff49a67814a48a2702d56faf2a624f9a6 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Sat, 29 Mar 2014 07:04:54 +0000 Subject: Intrinsics: add LLVMHalfElementsVectorType constraint This is like the LLVMMatchType, except the verifier checks that the second argument is a vector with the same base type and half the number of elements. This will be used by the ARM64 backend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205079 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/DerivedTypes.h | 20 ++++++++++++++++++++ include/llvm/IR/Intrinsics.h | 6 +++--- include/llvm/IR/Intrinsics.td | 4 ++++ lib/IR/Function.cpp | 12 +++++++++++- lib/IR/Verifier.cpp | 6 ++++++ utils/TableGen/IntrinsicEmitter.cpp | 5 ++++- 6 files changed, 48 insertions(+), 5 deletions(-) diff --git a/include/llvm/IR/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h index 758ef71a1f..71d9973bcb 100644 --- a/include/llvm/IR/DerivedTypes.h +++ b/include/llvm/IR/DerivedTypes.h @@ -400,6 +400,26 @@ public: return VectorType::get(EltTy, VTy->getNumElements()); } + /// VectorType::getHalfElementsVectorType - 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) { + unsigned NumElts = VTy->getNumElements(); + assert ((NumElts & 1) == 0 && + "Cannot halve vector with odd number of elements."); + return VectorType::get(VTy->getElementType(), NumElts/2); + } + + /// VectorType::getDoubleElementsVectorType - This static method returns + /// a VectorType with twice as many elements as the input type and the + /// same element type. + /// + static VectorType *getDoubleElementsVectorType(VectorType *VTy) { + unsigned NumElts = VTy->getNumElements(); + return VectorType::get(VTy->getElementType(), NumElts*2); + } + /// isValidElementType - Return true if the specified type is valid as a /// element type. static bool isValidElementType(Type *ElemTy); diff --git a/include/llvm/IR/Intrinsics.h b/include/llvm/IR/Intrinsics.h index b3e58b7cc4..839bbbd8b4 100644 --- a/include/llvm/IR/Intrinsics.h +++ b/include/llvm/IR/Intrinsics.h @@ -79,7 +79,7 @@ namespace Intrinsic { enum IITDescriptorKind { Void, VarArg, MMX, Metadata, Half, Float, Double, Integer, Vector, Pointer, Struct, - Argument, ExtendArgument, TruncArgument, + Argument, ExtendArgument, TruncArgument, HalfVecArgument } Kind; union { @@ -99,12 +99,12 @@ namespace Intrinsic { }; unsigned getArgumentNumber() const { assert(Kind == Argument || Kind == ExtendArgument || - Kind == TruncArgument); + Kind == TruncArgument || Kind == HalfVecArgument); return Argument_Info >> 2; } ArgKind getArgumentKind() const { assert(Kind == Argument || Kind == ExtendArgument || - Kind == TruncArgument); + Kind == TruncArgument || Kind == HalfVecArgument); return (ArgKind)(Argument_Info&3); } diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index 91bf99eab2..3e6c08dd23 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -113,6 +113,10 @@ class LLVMMatchType class LLVMExtendedType : LLVMMatchType; class LLVMTruncatedType : LLVMMatchType; +// Match the type of another intrinsic parameter that is expected to be a +// vector type, but change the element count to be half as many +class LLVMHalfElementsVectorType : LLVMMatchType; + def llvm_void_ty : LLVMType; def llvm_anyint_ty : LLVMType; def llvm_anyfloat_ty : LLVMType; diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp index f690ee0776..c2ea0e1e4d 100644 --- a/lib/IR/Function.cpp +++ b/lib/IR/Function.cpp @@ -470,7 +470,8 @@ enum IIT_Info { IIT_TRUNC_ARG = 24, IIT_ANYPTR = 25, IIT_V1 = 26, - IIT_VARARG = 27 + IIT_VARARG = 27, + IIT_HALF_VEC_ARG = 28 }; @@ -568,6 +569,12 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef Infos, ArgInfo)); return; } + case IIT_HALF_VEC_ARG: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back(IITDescriptor::get(IITDescriptor::HalfVecArgument, + ArgInfo)); + return; + } case IIT_EMPTYSTRUCT: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0)); return; @@ -672,6 +679,9 @@ static Type *DecodeFixedType(ArrayRef &Infos, assert(ITy->getBitWidth() % 2 == 0); return IntegerType::get(Context, ITy->getBitWidth() / 2); } + case IITDescriptor::HalfVecArgument: + return VectorType::getHalfElementsVectorType(cast( + Tys[D.getArgumentNumber()])); } llvm_unreachable("unhandled"); } diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index aa84f230d0..089ad1ca5f 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -2206,6 +2206,12 @@ bool Verifier::VerifyIntrinsicType(Type *Ty, return Ty != NewTy; } + case IITDescriptor::HalfVecArgument: + // This may only be used when referring to a previous vector argument. + return D.getArgumentNumber() >= ArgTys.size() || + !isa(ArgTys[D.getArgumentNumber()]) || + VectorType::getHalfElementsVectorType( + cast(ArgTys[D.getArgumentNumber()])) != Ty; } llvm_unreachable("unhandled"); } diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index dc32dfa858..7b0a2b6c6d 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/utils/TableGen/IntrinsicEmitter.cpp @@ -250,7 +250,8 @@ enum IIT_Info { IIT_TRUNC_ARG = 24, IIT_ANYPTR = 25, IIT_V1 = 26, - IIT_VARARG = 27 + IIT_VARARG = 27, + IIT_HALF_VEC_ARG = 28 }; @@ -296,6 +297,8 @@ static void EncodeFixedType(Record *R, std::vector &ArgCodes, Sig.push_back(IIT_EXTEND_ARG); else if (R->isSubClassOf("LLVMTruncatedType")) Sig.push_back(IIT_TRUNC_ARG); + else if (R->isSubClassOf("LLVMHalfElementsVectorType")) + Sig.push_back(IIT_HALF_VEC_ARG); else Sig.push_back(IIT_ARG); return Sig.push_back((Number << 2) | ArgCodes[Number]); -- cgit v1.2.3