diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2683,6 +2683,8 @@ bool isSVEBool() const { return getKind() == Kind::SveBool; } + bool isSVECount() const { return getKind() == Kind::SveCount; } + /// Determines whether the given kind corresponds to a placeholder type. static bool isPlaceholderTypeKind(Kind K) { return K >= Overload; diff --git a/clang/include/clang/Basic/AArch64SVEACLETypes.def b/clang/include/clang/Basic/AArch64SVEACLETypes.def --- a/clang/include/clang/Basic/AArch64SVEACLETypes.def +++ b/clang/include/clang/Basic/AArch64SVEACLETypes.def @@ -49,6 +49,11 @@ SVE_TYPE(Name, Id, SingletonId) #endif +#ifndef SVE_OPAQUE_TYPE +#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \ + SVE_TYPE(Name, Id, SingletonId) +#endif + //===- Vector point types -----------------------------------------------===// @@ -125,6 +130,9 @@ SVE_PREDICATE_TYPE("__SVBool_t", "__SVBool_t", SveBool, SveBoolTy, 16) +SVE_OPAQUE_TYPE("__SVCount_t", "__SVCount_t", SveCount, SveCountTy) + #undef SVE_VECTOR_TYPE #undef SVE_PREDICATE_TYPE +#undef SVE_OPAQUE_TYPE #undef SVE_TYPE diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2269,6 +2269,11 @@ Width = 0; \ Align = 16; \ break; +#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \ + case BuiltinType::Id: \ + Width = 0; \ + Align = 16; \ + break; #include "clang/Basic/AArch64SVEACLETypes.def" #define PPC_VECTOR_TYPE(Name, Id, Size) \ case BuiltinType::Id: \ @@ -4037,6 +4042,7 @@ #define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId, NumEls) \ if (EltTy->isBooleanType() && NumElts == NumEls) \ return SingletonId; +#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingleTonId) #include "clang/Basic/AArch64SVEACLETypes.def" } else if (Target->hasRISCVVTypes()) { uint64_t EltTySize = getTypeSize(EltTy); @@ -9439,9 +9445,10 @@ /// getSVETypeSize - Return SVE vector or predicate register size. static uint64_t getSVETypeSize(ASTContext &Context, const BuiltinType *Ty) { assert(Ty->isVLSTBuiltinType() && "Invalid SVE Type"); - return Ty->getKind() == BuiltinType::SveBool - ? (Context.getLangOpts().VScaleMin * 128) / Context.getCharWidth() - : Context.getLangOpts().VScaleMin * 128; + if (Ty->getKind() == BuiltinType::SveBool || + Ty->getKind() == BuiltinType::SveCount) + return (Context.getLangOpts().VScaleMin * 128) / Context.getCharWidth(); + return Context.getLangOpts().VScaleMin * 128; } bool ASTContext::areCompatibleSveTypes(QualType FirstType, diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3123,6 +3123,12 @@ Out << (type_name == InternalName ? "u" : "") << type_name.size() \ << type_name; \ break; +#define SVE_OPAQUE_TYPE(InternalName, MangledName, Id, SingletonId) \ + case BuiltinType::Id: \ + type_name = MangledName; \ + Out << (type_name == InternalName ? "u" : "") << type_name.size() \ + << type_name; \ + break; #include "clang/Basic/AArch64SVEACLETypes.def" #define PPC_VECTOR_TYPE(Name, Id, Size) \ case BuiltinType::Id: \ diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -722,7 +722,12 @@ #include "clang/Basic/AArch64SVEACLETypes.def" { ASTContext::BuiltinVectorTypeInfo Info = - CGM.getContext().getBuiltinVectorTypeInfo(BT); + // The debug info for svcount_t is the same as that for svbool_t + BT->getKind() == BuiltinType::SveCount + ? ASTContext::BuiltinVectorTypeInfo( + CGM.getContext().BoolTy, + llvm::ElementCount::getScalable(16), 1) + : CGM.getContext().getBuiltinVectorTypeInfo(BT); unsigned NumElemsPerVG = (Info.EC.getKnownMinValue() * Info.NumVectors) / 2; // Debuggers can't extract 1bit from a vector, so will display a diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -618,6 +618,8 @@ Info.EC.getKnownMinValue() * Info.NumVectors); } + case BuiltinType::SveCount: + return llvm::Type::getAArch64SvcountTy(getLLVMContext()); #define PPC_VECTOR_TYPE(Name, Id, Size) \ case BuiltinType::Id: \ ResultType = \ diff --git a/clang/test/AST/ast-dump-aarch64-sve-types.c b/clang/test/AST/ast-dump-aarch64-sve-types.c --- a/clang/test/AST/ast-dump-aarch64-sve-types.c +++ b/clang/test/AST/ast-dump-aarch64-sve-types.c @@ -47,3 +47,6 @@ // CHECK: TypedefDecl {{.*}} implicit __SVBool_t '__SVBool_t' // CHECK-NEXT: -BuiltinType {{.*}} '__SVBool_t' + +// CHECK: TypedefDecl {{.*}} implicit __SVCount_t '__SVCount_t' +// CHECK-NEXT: -BuiltinType {{.*}} '__SVCount_t' diff --git a/clang/test/CodeGen/aarch64-debug-sve-vector-types.c b/clang/test/CodeGen/aarch64-debug-sve-vector-types.c --- a/clang/test/CodeGen/aarch64-debug-sve-vector-types.c +++ b/clang/test/CodeGen/aarch64-debug-sve-vector-types.c @@ -9,6 +9,9 @@ // CHECK-DAG: ![[REALELTS1_64]] = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 1, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) __SVBool_t b8; + // CHECK-DAG: name: "__SVCount_t",{{.*}}, baseType: ![[CT1]] + __SVCount_t c8; + // CHECK-DAG: name: "__SVInt8_t",{{.*}}, baseType: ![[CT8:[0-9]+]] // CHECK-DAG: ![[CT8]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELTTYS8:[0-9]+]], flags: DIFlagVector, elements: ![[ELTS8:[0-9]+]]) // CHECK-DAG: ![[ELTTYS8]] = !DIBasicType(name: "signed char", size: 8, encoding: DW_ATE_signed_char) diff --git a/clang/test/CodeGen/aarch64-sve-inline-asm-crash.c b/clang/test/CodeGen/aarch64-sve-inline-asm-crash.c --- a/clang/test/CodeGen/aarch64-sve-inline-asm-crash.c +++ b/clang/test/CodeGen/aarch64-sve-inline-asm-crash.c @@ -20,5 +20,17 @@ return ret ; } +__SVCount_t funcB1(__SVCount_t in) +{ + __SVCount_t ret ; + asm volatile ( + "mov %[ret].b, %[in].b \n" + : [ret] "=w" (ret) + : [in] "w" (in) + :); + + return ret ; +} + // CHECK: funcB1 // CHECK-ERROR: fatal error: error in backend: Cannot select diff --git a/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp b/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp --- a/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp +++ b/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp @@ -31,6 +31,8 @@ void f12(S<__SVBFloat16_t>) {} // CHECK: _Z3f131SIu10__SVBool_tE void f13(S<__SVBool_t>) {} +// CHECK: _Z3f141SIu11__SVCount_tE +void f14(S<__SVCount_t>) {} // The tuple types don't use the internal name for mangling. diff --git a/clang/test/CodeGenCXX/aarch64-sve-typeinfo.cpp b/clang/test/CodeGenCXX/aarch64-sve-typeinfo.cpp --- a/clang/test/CodeGenCXX/aarch64-sve-typeinfo.cpp +++ b/clang/test/CodeGenCXX/aarch64-sve-typeinfo.cpp @@ -22,6 +22,7 @@ auto &bf16 = typeid(__SVBFloat16_t); auto &b8 = typeid(__SVBool_t); +auto &c8 = typeid(__SVCount_t); // CHECK-DAG: @_ZTSu10__SVInt8_t = {{.*}} c"u10__SVInt8_t\00" // CHECK-DAG: @_ZTIu10__SVInt8_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu10__SVInt8_t @@ -61,3 +62,6 @@ // CHECK-DAG: @_ZTSu10__SVBool_t = {{.*}} c"u10__SVBool_t\00" // CHECK-DAG: @_ZTIu10__SVBool_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu10__SVBool_t + +// CHECK-DAG: @_ZTSu11__SVCount_t = {{.*}} c"u11__SVCount_t\00" +// CHECK-DAG: @_ZTIu11__SVCount_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu11__SVCount_t diff --git a/clang/unittests/AST/SizelessTypesTest.cpp b/clang/unittests/AST/SizelessTypesTest.cpp --- a/clang/unittests/AST/SizelessTypesTest.cpp +++ b/clang/unittests/AST/SizelessTypesTest.cpp @@ -45,6 +45,7 @@ ASSERT_TRUE(Ctx.SveBFloat16Ty->isSizelessBuiltinType()); ASSERT_TRUE(Ctx.SveBoolTy->isSizelessBuiltinType()); + ASSERT_TRUE(Ctx.SveCountTy->isSizelessBuiltinType()); ASSERT_FALSE(Ctx.VoidTy->isSizelessBuiltinType()); ASSERT_FALSE(Ctx.PseudoObjectTy->isSizelessBuiltinType()); @@ -55,6 +56,12 @@ Ctx.getLValueReferenceType(Ctx.SveBoolTy)->isSizelessBuiltinType()); ASSERT_FALSE( Ctx.getRValueReferenceType(Ctx.SveBoolTy)->isSizelessBuiltinType()); + + ASSERT_FALSE(Ctx.getPointerType(Ctx.SveCountTy)->isSizelessBuiltinType()); + ASSERT_FALSE( + Ctx.getLValueReferenceType(Ctx.SveCountTy)->isSizelessBuiltinType()); + ASSERT_FALSE( + Ctx.getRValueReferenceType(Ctx.SveCountTy)->isSizelessBuiltinType()); } TEST_F(SizelessTypeTester, TestSizeless) { @@ -75,6 +82,7 @@ ASSERT_TRUE(Ctx.SveBFloat16Ty->isSizelessType()); ASSERT_TRUE(Ctx.SveBoolTy->isSizelessType()); + ASSERT_TRUE(Ctx.SveCountTy->isSizelessType()); ASSERT_FALSE(Ctx.VoidTy->isSizelessType()); ASSERT_FALSE(Ctx.PseudoObjectTy->isSizelessType()); @@ -83,4 +91,8 @@ ASSERT_FALSE(Ctx.getPointerType(Ctx.SveBoolTy)->isSizelessType()); ASSERT_FALSE(Ctx.getLValueReferenceType(Ctx.SveBoolTy)->isSizelessType()); ASSERT_FALSE(Ctx.getRValueReferenceType(Ctx.SveBoolTy)->isSizelessType()); + + ASSERT_FALSE(Ctx.getPointerType(Ctx.SveCountTy)->isSizelessType()); + ASSERT_FALSE(Ctx.getLValueReferenceType(Ctx.SveCountTy)->isSizelessType()); + ASSERT_FALSE(Ctx.getRValueReferenceType(Ctx.SveCountTy)->isSizelessType()); }