diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3623,6 +3623,31 @@ x86_mmx +AArch64 Predicate-as-Counter Type +""""""""""""""""""""""""""""""""" + +:Overview: + +The ``aarch64_svcount`` type represents the type of a predicate-as-counter value +held in a AArch64 SVE predicate register. Such a value contains information +about the number of active lanes, the element width and a bit that tells whether +the generated mask should be inverted. Target-specific intrinsics should be used +to move the aarch64_svcount value to/from a predicate vector. + +There are certain limitations on the type: +* The type can be used for function parameters and return values. +* The supported LLVM operations on this type are strictly limited to ``load``, + ``store``, ``phi`` and ``alloca`` instructions. + +The predicate-as-counter type is a scalable type. + +:Syntax: + +:: + + aarch64_svcount + + .. _t_pointer: Pointer Type diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -175,6 +175,7 @@ TYPE_CODE_X86_AMX = 24, // X86 AMX TYPE_CODE_OPAQUE_POINTER = 25, // OPAQUE_POINTER: [addrspace] + TYPE_CODE_AARCH64_SVCOUNT = 26, // AArch64 predicate-as-counter }; enum OperandBundleTagCode { diff --git a/llvm/include/llvm/CodeGen/ValueTypes.td b/llvm/include/llvm/CodeGen/ValueTypes.td --- a/llvm/include/llvm/CodeGen/ValueTypes.td +++ b/llvm/include/llvm/CodeGen/ValueTypes.td @@ -227,6 +227,8 @@ def externref : ValueType<0, 184>; // WebAssembly's externref type def x86amx : ValueType<8192, 185>; // X86 AMX value def i64x8 : ValueType<512, 186>; // 8 Consecutive GPRs (AArch64) +def aarch64svcount + : ValueType<16, 187>; // AArch64 predicate-as-counter def token : ValueType<0, 248>; // TokenTy def MetadataVT : ValueType<0, 249>; // Metadata diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h --- a/llvm/include/llvm/IR/DataLayout.h +++ b/llvm/include/llvm/IR/DataLayout.h @@ -705,6 +705,8 @@ // only 80 bits contain information. case Type::X86_FP80TyID: return TypeSize::Fixed(80); + case Type::AArch64SvcountTyID: + return TypeSize::Scalable(16); case Type::FixedVectorTyID: case Type::ScalableVectorTyID: { VectorType *VTy = cast(Ty); diff --git a/llvm/include/llvm/IR/Type.h b/llvm/include/llvm/IR/Type.h --- a/llvm/include/llvm/IR/Type.h +++ b/llvm/include/llvm/IR/Type.h @@ -65,6 +65,7 @@ MetadataTyID, ///< Metadata X86_MMXTyID, ///< MMX vectors (64 bits, X86 specific) X86_AMXTyID, ///< AMX vectors (8192 bits, X86 specific) + AArch64SvcountTyID, /// AArch64 predicate-as-counter (vscale x 2bits) TokenTyID, ///< Tokens // Derived types... see DerivedTypes.h file. @@ -180,6 +181,9 @@ /// Return true if this is X86 AMX. bool isX86_AMXTy() const { return getTypeID() == X86_AMXTyID; } + /// Return true if this is a AArch64 Predicate-as-counter type. + bool isAArch64SvcountTy() const { return getTypeID() == AArch64SvcountTyID; } + /// Return true if this is a FP type or a vector of FP. bool isFPOrFPVectorTy() const { return getScalarType()->isFloatingPointTy(); } @@ -430,6 +434,7 @@ static Type *getPPC_FP128Ty(LLVMContext &C); static Type *getX86_MMXTy(LLVMContext &C); static Type *getX86_AMXTy(LLVMContext &C); + static Type *getAArch64SvcountTy(LLVMContext &C); static Type *getTokenTy(LLVMContext &C); static IntegerType *getIntNTy(LLVMContext &C, unsigned N); static IntegerType *getInt1Ty(LLVMContext &C); diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -793,6 +793,7 @@ TYPEKEYWORD("metadata", Type::getMetadataTy(Context)); TYPEKEYWORD("x86_mmx", Type::getX86_MMXTy(Context)); TYPEKEYWORD("x86_amx", Type::getX86_AMXTy(Context)); + TYPEKEYWORD("aarch64_svcount", Type::getAArch64SvcountTy(Context)); TYPEKEYWORD("token", Type::getTokenTy(Context)); if (Keyword == "ptr") { diff --git a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp @@ -185,6 +185,7 @@ STRINGIFY_CODE(TYPE_CODE, PPC_FP128) STRINGIFY_CODE(TYPE_CODE, METADATA) STRINGIFY_CODE(TYPE_CODE, X86_MMX) + STRINGIFY_CODE(TYPE_CODE, AARCH64_SVCOUNT) STRINGIFY_CODE(TYPE_CODE, STRUCT_ANON) STRINGIFY_CODE(TYPE_CODE, STRUCT_NAME) STRINGIFY_CODE(TYPE_CODE, STRUCT_NAMED) diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2256,6 +2256,9 @@ case bitc::TYPE_CODE_X86_AMX: // X86_AMX ResultTy = Type::getX86_AMXTy(Context); break; + case bitc::TYPE_CODE_AARCH64_SVCOUNT: // AArch64Svcount + ResultTy = Type::getAArch64SvcountTy(Context); + break; case bitc::TYPE_CODE_TOKEN: // TOKEN ResultTy = Type::getTokenTy(Context); break; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -950,6 +950,9 @@ case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break; case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break; case Type::X86_AMXTyID: Code = bitc::TYPE_CODE_X86_AMX; break; + case Type::AArch64SvcountTyID: + Code = bitc::TYPE_CODE_AARCH64_SVCOUNT; + break; case Type::TokenTyID: Code = bitc::TYPE_CODE_TOKEN; break; case Type::IntegerTyID: // INTEGER: [width] diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -548,6 +548,9 @@ case Type::MetadataTyID: OS << "metadata"; return; case Type::X86_MMXTyID: OS << "x86_mmx"; return; case Type::X86_AMXTyID: OS << "x86_amx"; return; + case Type::AArch64SvcountTyID: + OS << "aarch64_svcount"; + return; case Type::TokenTyID: OS << "token"; return; case Type::IntegerTyID: OS << 'i' << cast(Ty)->getBitWidth(); diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -1464,7 +1464,7 @@ // Basic type instances. Type VoidTy, LabelTy, HalfTy, BFloatTy, FloatTy, DoubleTy, MetadataTy, TokenTy; - Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy, X86_AMXTy; + Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy, X86_AMXTy, AArch64SvcountTy; IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty, Int128Ty; std::unique_ptr TheNoneToken; diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp --- a/llvm/lib/IR/LLVMContextImpl.cpp +++ b/llvm/lib/IR/LLVMContextImpl.cpp @@ -45,7 +45,8 @@ MetadataTy(C, Type::MetadataTyID), TokenTy(C, Type::TokenTyID), X86_FP80Ty(C, Type::X86_FP80TyID), FP128Ty(C, Type::FP128TyID), PPC_FP128Ty(C, Type::PPC_FP128TyID), X86_MMXTy(C, Type::X86_MMXTyID), - X86_AMXTy(C, Type::X86_AMXTyID), Int1Ty(C, 1), Int8Ty(C, 8), + X86_AMXTy(C, Type::X86_AMXTyID), + AArch64SvcountTy(C, Type::AArch64SvcountTyID), Int1Ty(C, 1), Int8Ty(C, 8), Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64), Int128Ty(C, 128) { if (OpaquePointersCL.getNumOccurrences()) { OpaquePointers = OpaquePointersCL; diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp --- a/llvm/lib/IR/Type.cpp +++ b/llvm/lib/IR/Type.cpp @@ -232,7 +232,9 @@ Type *Type::getPPC_FP128Ty(LLVMContext &C) { return &C.pImpl->PPC_FP128Ty; } Type *Type::getX86_MMXTy(LLVMContext &C) { return &C.pImpl->X86_MMXTy; } Type *Type::getX86_AMXTy(LLVMContext &C) { return &C.pImpl->X86_AMXTy; } - +Type *Type::getAArch64SvcountTy(LLVMContext &C) { + return &C.pImpl->AArch64SvcountTy; +} IntegerType *Type::getInt1Ty(LLVMContext &C) { return &C.pImpl->Int1Ty; } IntegerType *Type::getInt8Ty(LLVMContext &C) { return &C.pImpl->Int8Ty; } IntegerType *Type::getInt16Ty(LLVMContext &C) { return &C.pImpl->Int16Ty; } diff --git a/llvm/test/Assembler/aarch64_svcount.ll b/llvm/test/Assembler/aarch64_svcount.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Assembler/aarch64_svcount.ll @@ -0,0 +1,17 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s +; RUN: verify-uselistorder %s +; Basic smoke test for aarch64_svcount type. + +define aarch64_svcount @func1(aarch64_svcount %A) { +; CHECK-LABEL: @func1 +; CHECK: ret aarch64_svcount %A + ret aarch64_svcount %A +} + +define aarch64_svcount @func2(aarch64_svcount %A) { +; CHECK-LABEL: @func2 +; CHECK: %1 = call aarch64_svcount @func1(aarch64_svcount %A) +; CHECK-NEXT: ret aarch64_svcount %1 + %1 = call aarch64_svcount @func1(aarch64_svcount %A); + ret aarch64_svcount %1 +}