Index: include/llvm/IR/Intrinsics.h =================================================================== --- include/llvm/IR/Intrinsics.h +++ include/llvm/IR/Intrinsics.h @@ -100,7 +100,8 @@ Void, VarArg, MMX, Token, Metadata, Half, Float, Double, Integer, Vector, Pointer, Struct, Argument, ExtendArgument, TruncArgument, HalfVecArgument, - SameVecWidthArgument, PtrToArgument, PtrToElt, VecOfAnyPtrsToElt + SameVecWidthArgument, PtrToArgument, PtrToElt, VecOfAnyPtrsToElt, + VecElementArgument } Kind; union { @@ -124,13 +125,14 @@ assert(Kind == Argument || Kind == ExtendArgument || Kind == TruncArgument || Kind == HalfVecArgument || Kind == SameVecWidthArgument || Kind == PtrToArgument || - Kind == PtrToElt); + Kind == PtrToElt || Kind == VecElementArgument); return Argument_Info >> 3; } ArgKind getArgumentKind() const { assert(Kind == Argument || Kind == ExtendArgument || Kind == TruncArgument || Kind == HalfVecArgument || - Kind == SameVecWidthArgument || Kind == PtrToArgument); + Kind == SameVecWidthArgument || Kind == PtrToArgument || + Kind == VecElementArgument); return (ArgKind)(Argument_Info & 7); } Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -160,6 +160,7 @@ class LLVMPointerTo : LLVMMatchType; class LLVMPointerToElt : LLVMMatchType; class LLVMVectorOfAnyPointersToElt : LLVMMatchType; +class LLVMVectorElementType : 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 Index: lib/IR/Function.cpp =================================================================== --- lib/IR/Function.cpp +++ lib/IR/Function.cpp @@ -673,7 +673,8 @@ IIT_V1024 = 37, IIT_STRUCT6 = 38, IIT_STRUCT7 = 39, - IIT_STRUCT8 = 40 + IIT_STRUCT8 = 40, + IIT_VEC_ELEMENT = 41 }; static void DecodeIITType(unsigned &NextElt, ArrayRef Infos, @@ -835,6 +836,12 @@ DecodeIITType(NextElt, Infos, OutputTable); return; } + case IIT_VEC_ELEMENT: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back(IITDescriptor::get(IITDescriptor::VecElementArgument, + ArgInfo)); + return; + } } llvm_unreachable("unhandled"); } @@ -950,6 +957,12 @@ case IITDescriptor::VecOfAnyPtrsToElt: // Return the overloaded type (which determines the pointers address space) return Tys[D.getOverloadArgNumber()]; + case IITDescriptor::VecElementArgument: { + Type *Ty = Tys[D.getArgumentNumber()]; + if (VectorType *VTy = dyn_cast(Ty)) + return VTy->getElementType(); + llvm_unreachable("Expected an argument of Vector Type"); + } } llvm_unreachable("unhandled"); } @@ -1171,6 +1184,12 @@ return ThisArgEltTy->getElementType() != ReferenceType->getVectorElementType(); } + case IITDescriptor::VecElementArgument: { + if (D.getArgumentNumber() >= ArgTys.size()) + return true; + auto *ReferenceType = dyn_cast(ArgTys[D.getArgumentNumber()]); + return !ReferenceType || Ty != ReferenceType->getElementType(); + } } llvm_unreachable("unhandled"); } Index: utils/TableGen/IntrinsicEmitter.cpp =================================================================== --- utils/TableGen/IntrinsicEmitter.cpp +++ utils/TableGen/IntrinsicEmitter.cpp @@ -217,7 +217,8 @@ IIT_V1024 = 37, IIT_STRUCT6 = 38, IIT_STRUCT7 = 39, - IIT_STRUCT8 = 40 + IIT_STRUCT8 = 40, + IIT_VEC_ELEMENT = 41 }; static void EncodeFixedValueType(MVT::SimpleValueType VT, @@ -286,6 +287,8 @@ return; } else if (R->isSubClassOf("LLVMPointerToElt")) Sig.push_back(IIT_PTR_TO_ELT); + else if (R->isSubClassOf("LLVMVectorElementType")) + Sig.push_back(IIT_VEC_ELEMENT); else Sig.push_back(IIT_ARG); return Sig.push_back((Number << 3) | ArgCodes[Number]);