diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 29a3fbade10e5..755dd560a6f1d 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -423,15 +423,16 @@ endif() option(LLVM_ENABLE_EXPENSIVE_CHECKS "Enable expensive checks" OFF) # While adding scalable vector support to LLVM, we temporarily want to -# allow an implicit conversion of TypeSize to uint64_t. This CMake flag -# enables a more strict conversion where it asserts that the type is not -# a scalable vector type. +# allow an implicit conversion of TypeSize to uint64_t, and to allow +# code to get the fixed number of elements from a possibly scalable vector. +# This CMake flag enables a more strict mode where it asserts that the type +# is not a scalable vector type. # # Enabling this flag makes it easier to find cases where the compiler makes # assumptions on the size being 'fixed size', when building tests for # SVE/SVE2 or other scalable vector architectures. option(LLVM_ENABLE_STRICT_FIXED_SIZE_VECTORS - "Enable assertions that type is not scalable in implicit conversion from TypeSize to uint64_t" OFF) + "Enable assertions that type is not scalable in implicit conversion from TypeSize to uint64_t and calls to getNumElements" OFF) set(LLVM_ABI_BREAKING_CHECKS "WITH_ASSERTS" CACHE STRING "Enable abi-breaking checks. Can be WITH_ASSERTS, FORCE_ON or FORCE_OFF.") diff --git a/llvm/include/llvm/IR/DerivedTypes.h b/llvm/include/llvm/IR/DerivedTypes.h index 75c48f301026f..dc0d2012d8fe8 100644 --- a/llvm/include/llvm/IR/DerivedTypes.h +++ b/llvm/include/llvm/IR/DerivedTypes.h @@ -417,7 +417,21 @@ class VectorType : public Type { /// Get the number of elements in this vector. It does not make sense to call /// this function on a scalable vector, and this will be moved into /// FixedVectorType in a future commit - unsigned getNumElements() const { return EC.Min; } + unsigned getNumElements() const { + ElementCount EC = getElementCount(); +#ifdef STRICT_FIXED_SIZE_VECTORS + assert(!EC.Scalable && + "Request for fixed number of elements from scalable vector"); + return EC.Min; +#else + if (EC.Scalable) + WithColor::warning() + << "The code that requested the fixed number of elements has made " + "the assumption that this vector is not scalable. This assumption " + "was not correct, and this may lead to broken code\n"; + return EC.Min; +#endif + } Type *getElementType() const { return ContainedType; } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 685bb948f974c..5c8f9b0a81b5d 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -653,10 +653,11 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) { case Type::FixedVectorTyID: case Type::ScalableVectorTyID: { VectorType *PTy = cast(Ty); + ElementCount EC = PTy->getElementCount(); OS << "<"; - if (PTy->isScalable()) + if (EC.Scalable) OS << "vscale x "; - OS << PTy->getNumElements() << " x "; + OS << EC.Min << " x "; print(PTy->getElementType(), OS); OS << '>'; return; diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index ec390b36b3a9b..972fe0ea85d35 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -644,10 +644,10 @@ static std::string getMangledTypeStr(Type* Ty) { // Ensure nested function types are distinguishable. Result += "f"; } else if (VectorType* VTy = dyn_cast(Ty)) { - if (VTy->isScalable()) + ElementCount EC = VTy->getElementCount(); + if (EC.Scalable) Result += "nx"; - Result += "v" + utostr(VTy->getNumElements()) + - getMangledTypeStr(VTy->getElementType()); + Result += "v" + utostr(EC.Min) + getMangledTypeStr(VTy->getElementType()); } else if (Ty) { switch (Ty->getTypeID()) { default: llvm_unreachable("Unhandled type");