Index: include/llvm/IR/Intrinsics.h =================================================================== --- include/llvm/IR/Intrinsics.h +++ include/llvm/IR/Intrinsics.h @@ -77,7 +77,7 @@ Void, VarArg, MMX, Metadata, Half, Float, Double, Integer, Vector, Pointer, Struct, Argument, ExtendArgument, TruncArgument, HalfVecArgument, - SameVecWidthArgument, PtrToArgument + SameVecWidthArgument, PtrToArgument, VecOfPtrsToElt } Kind; union { @@ -99,13 +99,15 @@ unsigned getArgumentNumber() const { assert(Kind == Argument || Kind == ExtendArgument || Kind == TruncArgument || Kind == HalfVecArgument || - Kind == SameVecWidthArgument || Kind == PtrToArgument); + Kind == SameVecWidthArgument || Kind == PtrToArgument || + Kind == VecOfPtrsToElt); 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 == VecOfPtrsToElt); return (ArgKind)(Argument_Info & 7); } Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -117,6 +117,7 @@ ValueType ElTy = elty.VT; } class LLVMPointerTo : LLVMMatchType; +class LLVMVectorOfPointersToElt : 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 @@ -584,6 +585,19 @@ [LLVMPointerTo<0>, llvm_i32_ty, LLVMVectorSameWidth<0, llvm_i1_ty>, LLVMMatchType<0>], [IntrReadArgMem]>; + +def int_masked_gather: Intrinsic<[llvm_anyvector_ty], + [LLVMVectorOfPointersToElt<0>, llvm_i32_ty, + LLVMVectorSameWidth<0, llvm_i1_ty>, + LLVMMatchType<0>], + [IntrReadArgMem]>; + +def int_masked_scatter: Intrinsic<[], + [llvm_anyvector_ty, + LLVMVectorOfPointersToElt<0>, llvm_i32_ty, + LLVMVectorSameWidth<0, llvm_i1_ty>], + [IntrReadWriteArgMem]>; + //===----------------------------------------------------------------------===// // Target-specific intrinsics //===----------------------------------------------------------------------===// Index: lib/IR/Function.cpp =================================================================== --- lib/IR/Function.cpp +++ lib/IR/Function.cpp @@ -542,7 +542,8 @@ IIT_VARARG = 28, IIT_HALF_VEC_ARG = 29, IIT_SAME_VEC_WIDTH_ARG = 30, - IIT_PTR_TO_ARG = 31 + IIT_PTR_TO_ARG = 31, + IIT_VEC_OF_PTRS_TO_ELT = 32 }; @@ -662,6 +663,12 @@ ArgInfo)); return; } + case IIT_VEC_OF_PTRS_TO_ELT: { + unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]); + OutputTable.push_back(IITDescriptor::get(IITDescriptor::VecOfPtrsToElt, + ArgInfo)); + return; + } case IIT_EMPTYSTRUCT: OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0)); return; @@ -781,6 +788,15 @@ Type *Ty = Tys[D.getArgumentNumber()]; return PointerType::getUnqual(Ty); } + case IITDescriptor::VecOfPtrsToElt: { + Type *Ty = Tys[D.getArgumentNumber()]; + VectorType *VTy = dyn_cast(Ty); + if (!VTy) + llvm_unreachable("Expected an argument of Vector Type"); + Type *EltTy = VTy->getVectorElementType(); + return VectorType::get(PointerType::getUnqual(EltTy), + VTy->getNumElements()); + } } llvm_unreachable("unhandled"); } Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -2555,6 +2555,21 @@ PointerType *ThisArgType = dyn_cast(Ty); return (!ThisArgType || ThisArgType->getElementType() != ReferenceType); } + case IITDescriptor::VecOfPtrsToElt: { + if (D.getArgumentNumber() >= ArgTys.size()) + return true; + VectorType * ReferenceType = + dyn_cast (ArgTys[D.getArgumentNumber()]); + VectorType *ThisArgVecTy = dyn_cast(Ty); + if (!ThisArgVecTy || !ReferenceType || + (ReferenceType->getVectorNumElements() != + ThisArgVecTy->getVectorNumElements())) + return true; + PointerType *ThisArgEltTy = dyn_cast(ThisArgVecTy->getVectorElementType()); + if (!ThisArgEltTy) + return true; + return !(ThisArgEltTy->getElementType() == ReferenceType->getVectorElementType()); + } } llvm_unreachable("unhandled"); } Index: utils/TableGen/IntrinsicEmitter.cpp =================================================================== --- utils/TableGen/IntrinsicEmitter.cpp +++ utils/TableGen/IntrinsicEmitter.cpp @@ -259,7 +259,8 @@ IIT_VARARG = 28, IIT_HALF_VEC_ARG = 29, IIT_SAME_VEC_WIDTH_ARG = 30, - IIT_PTR_TO_ARG = 31 + IIT_PTR_TO_ARG = 31, + IIT_VEC_OF_PTRS_TO_ELT = 32 }; @@ -314,9 +315,10 @@ EncodeFixedValueType(VT, Sig); return; } - else if (R->isSubClassOf("LLVMPointerTo")) { + else if (R->isSubClassOf("LLVMPointerTo")) Sig.push_back(IIT_PTR_TO_ARG); - } + else if (R->isSubClassOf("LLVMVectorOfPointersToElt")) + Sig.push_back(IIT_VEC_OF_PTRS_TO_ELT); else Sig.push_back(IIT_ARG); return Sig.push_back((Number << 3) | ArgCodes[Number]);