summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/IR/Intrinsics.h8
-rw-r--r--llvm/include/llvm/IR/Intrinsics.td14
-rw-r--r--llvm/lib/IR/Function.cpp18
-rw-r--r--llvm/lib/IR/Verifier.cpp17
-rw-r--r--llvm/utils/TableGen/IntrinsicEmitter.cpp8
5 files changed, 58 insertions, 7 deletions
diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index addd78cea4e..a66bd2cd7d9 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -77,7 +77,7 @@ namespace Intrinsic {
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 @@ namespace Intrinsic {
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);
}
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 5a304db09f2..1326a8330d5 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -117,6 +117,7 @@ class LLVMVectorSameWidth<int num, LLVMType elty>
ValueType ElTy = elty.VT;
}
class LLVMPointerTo<int num> : LLVMMatchType<num>;
+class LLVMVectorOfPointersToElt<int num> : LLVMMatchType<num>;
// 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 @@ def int_masked_load : Intrinsic<[llvm_anyvector_ty],
[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
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 070513edef2..fe44f17d686 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -542,7 +542,8 @@ enum IIT_Info {
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 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
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 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
Type *Ty = Tys[D.getArgumentNumber()];
return PointerType::getUnqual(Ty);
}
+ case IITDescriptor::VecOfPtrsToElt: {
+ Type *Ty = Tys[D.getArgumentNumber()];
+ VectorType *VTy = dyn_cast<VectorType>(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");
}
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 29eddfe2541..a7b705410d7 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2555,6 +2555,23 @@ bool Verifier::VerifyIntrinsicType(Type *Ty,
PointerType *ThisArgType = dyn_cast<PointerType>(Ty);
return (!ThisArgType || ThisArgType->getElementType() != ReferenceType);
}
+ case IITDescriptor::VecOfPtrsToElt: {
+ if (D.getArgumentNumber() >= ArgTys.size())
+ return true;
+ VectorType * ReferenceType =
+ dyn_cast<VectorType> (ArgTys[D.getArgumentNumber()]);
+ VectorType *ThisArgVecTy = dyn_cast<VectorType>(Ty);
+ if (!ThisArgVecTy || !ReferenceType ||
+ (ReferenceType->getVectorNumElements() !=
+ ThisArgVecTy->getVectorNumElements()))
+ return true;
+ PointerType *ThisArgEltTy =
+ dyn_cast<PointerType>(ThisArgVecTy->getVectorElementType());
+ if (!ThisArgEltTy)
+ return true;
+ return (!(ThisArgEltTy->getElementType() ==
+ ReferenceType->getVectorElementType()));
+ }
}
llvm_unreachable("unhandled");
}
diff --git a/llvm/utils/TableGen/IntrinsicEmitter.cpp b/llvm/utils/TableGen/IntrinsicEmitter.cpp
index 87f9c90dc4a..e533d89326c 100644
--- a/llvm/utils/TableGen/IntrinsicEmitter.cpp
+++ b/llvm/utils/TableGen/IntrinsicEmitter.cpp
@@ -259,7 +259,8 @@ enum IIT_Info {
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 @@ static void EncodeFixedType(Record *R, std::vector<unsigned char> &ArgCodes,
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]);
OpenPOWER on IntegriCloud