summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/Function.cpp
diff options
context:
space:
mode:
authorCullen Rhodes <cullen.rhodes@arm.com>2019-08-27 12:57:09 +0000
committerCullen Rhodes <cullen.rhodes@arm.com>2019-08-27 12:57:09 +0000
commit2ba5d64a80d0debaec396dbd512e59de9cc82e48 (patch)
tree943ce51d8e70035e9c2bde09771b43b350b135ae /llvm/lib/IR/Function.cpp
parent0299dbd2ae89e81584cf95571ef0549862e10fea (diff)
downloadbcm5719-llvm-2ba5d64a80d0debaec396dbd512e59de9cc82e48.tar.gz
bcm5719-llvm-2ba5d64a80d0debaec396dbd512e59de9cc82e48.zip
[IntrinsicEmitter] Support scalable vectors in intrinsics
Summary: This patch adds support for scalable vectors in intrinsics, enabling intrinsics such as the following to be defined: declare <vscale x 4 x i32> @llvm.something.nxv4i32(<vscale x 4 x i32>) Support for this is implemented by defining a new type descriptor for scalable vectors and adding mangling support for scalable vector types in the name mangling scheme used by 'any' types in intrinsic signatures. Tests have been added for IRBuilder to test scalable vectors work as expected when using intrinsics through this interface. This required implementing an intrinsic that is explicitly defined with scalable vectors, e.g. LLVMType<nxv4i32>, an SVE floating-point convert intrinsic was used for this. The behaviour of the overloaded type LLVMScalarOrSameVectorWidth with scalable vectors is tested using the existing masked load intrinsic. Also added an .ll test to test the Verifier catches a bad intrinsic argument when passing a fixed-width predicate (mask) to the masked.load intrinsic where a scalable is expected. Patch by Paul Walker Reviewed By: sdesmalen Differential Revision: https://reviews.llvm.org/D65930 llvm-svn: 370053
Diffstat (limited to 'llvm/lib/IR/Function.cpp')
-rw-r--r--llvm/lib/IR/Function.cpp35
1 files changed, 28 insertions, 7 deletions
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 462458d7065..34aad7ddd03 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -611,9 +611,11 @@ static std::string getMangledTypeStr(Type* Ty) {
Result += "vararg";
// Ensure nested function types are distinguishable.
Result += "f";
- } else if (isa<VectorType>(Ty)) {
- Result += "v" + utostr(Ty->getVectorNumElements()) +
- getMangledTypeStr(Ty->getVectorElementType());
+ } else if (VectorType* VTy = dyn_cast<VectorType>(Ty)) {
+ if (VTy->isScalable())
+ Result += "nx";
+ Result += "v" + utostr(VTy->getVectorNumElements()) +
+ getMangledTypeStr(VTy->getVectorElementType());
} else if (Ty) {
switch (Ty->getTypeID()) {
default: llvm_unreachable("Unhandled type");
@@ -700,7 +702,8 @@ enum IIT_Info {
IIT_STRUCT7 = 39,
IIT_STRUCT8 = 40,
IIT_F128 = 41,
- IIT_VEC_ELEMENT = 42
+ IIT_VEC_ELEMENT = 42,
+ IIT_SCALABLE_VEC = 43
};
static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
@@ -871,6 +874,12 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,
ArgInfo));
return;
}
+ case IIT_SCALABLE_VEC: {
+ OutputTable.push_back(IITDescriptor::get(IITDescriptor::ScalableVecArgument,
+ 0));
+ DecodeIITType(NextElt, Infos, OutputTable);
+ return;
+ }
}
llvm_unreachable("unhandled");
}
@@ -968,7 +977,7 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
Type *EltTy = DecodeFixedType(Infos, Tys, Context);
Type *Ty = Tys[D.getArgumentNumber()];
if (auto *VTy = dyn_cast<VectorType>(Ty))
- return VectorType::get(EltTy, VTy->getNumElements());
+ return VectorType::get(EltTy, VTy->getElementCount());
return EltTy;
}
case IITDescriptor::PtrToArgument: {
@@ -992,6 +1001,11 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,
case IITDescriptor::VecOfAnyPtrsToElt:
// Return the overloaded type (which determines the pointers address space)
return Tys[D.getOverloadArgNumber()];
+ case IITDescriptor::ScalableVecArgument: {
+ Type *Ty = DecodeFixedType(Infos, Tys, Context);
+ return VectorType::get(Ty->getVectorElementType(),
+ { Ty->getVectorNumElements(), true });
+ }
}
llvm_unreachable("unhandled");
}
@@ -1191,8 +1205,8 @@ static bool matchIntrinsicType(
return true;
Type *EltTy = Ty;
if (ThisArgType) {
- if (ReferenceType->getVectorNumElements() !=
- ThisArgType->getVectorNumElements())
+ if (ReferenceType->getElementCount() !=
+ ThisArgType->getElementCount())
return true;
EltTy = ThisArgType->getVectorElementType();
}
@@ -1255,6 +1269,13 @@ static bool matchIntrinsicType(
auto *ReferenceType = dyn_cast<VectorType>(ArgTys[D.getArgumentNumber()]);
return !ReferenceType || Ty != ReferenceType->getElementType();
}
+ case IITDescriptor::ScalableVecArgument: {
+ VectorType *VTy = dyn_cast<VectorType>(Ty);
+ if (!VTy || !VTy->isScalable())
+ return true;
+ return matchIntrinsicType(VTy, Infos, ArgTys, DeferredChecks,
+ IsDeferredCheck);
+ }
}
llvm_unreachable("unhandled");
}
OpenPOWER on IntegriCloud