c-rhodes updated this revision to Diff 285285.
c-rhodes marked an inline comment as not done.
c-rhodes added a comment.
Address @rsandifo-arm comments.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D85736/new/
https://reviews.llvm.org/D85736
Files:
clang/include/clang/AST/ASTContext.h
clang/include/clang/AST/Type.h
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Sema/Overload.h
clang/include/clang/Sema/Sema.h
clang/lib/AST/ASTContext.cpp
clang/lib/AST/JSONNodeDumper.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/AST/Type.cpp
clang/lib/AST/TypePrinter.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/SemaType.cpp
clang/test/Sema/attr-arm-sve-vector-bits.c
clang/test/SemaCXX/attr-arm-sve-vector-bits.cpp
Index: clang/test/SemaCXX/attr-arm-sve-vector-bits.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/attr-arm-sve-vector-bits.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fsyntax-only -verify -std=c++11 -msve-vector-bits=512 -fallow-half-arguments-and-returns %s
+// expected-no-diagnostics
+
+#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL
+
+typedef __SVInt8_t svint8_t;
+typedef svint8_t fixed_int8_t __attribute__((arm_sve_vector_bits(N)));
+
+template<typename T> struct S { T var; };
+
+S<fixed_int8_t> s;
+
+svint8_t to_svint8_t(fixed_int8_t x) { return x; }
+fixed_int8_t from_svint8_t(svint8_t x) { return x; }
Index: clang/test/Sema/attr-arm-sve-vector-bits.c
===================================================================
--- clang/test/Sema/attr-arm-sve-vector-bits.c
+++ clang/test/Sema/attr-arm-sve-vector-bits.c
@@ -102,8 +102,11 @@
svint8_t ss8;
void *sel __attribute__((unused));
- sel = c ? ss8 : fs8; // expected-error {{incompatible operand types ('svint8_t' (aka '__SVInt8_t') and 'fixed_int8_t' (aka '__SVInt8_t'))}}
- sel = c ? fs8 : ss8; // expected-error {{incompatible operand types ('fixed_int8_t' (aka '__SVInt8_t') and 'svint8_t' (aka '__SVInt8_t'))}}
+ sel = c ? ss8 : fs8; // expected-error {{cannot convert between fixed-length and sizeless vector}}
+ sel = c ? fs8 : ss8; // expected-error {{cannot convert between fixed-length and sizeless vector}}
+
+ sel = fs8 + ss8; // expected-error {{cannot convert between fixed-length and sizeless vector}}
+ sel = ss8 + fs8; // expected-error {{cannot convert between fixed-length and sizeless vector}}
}
// --------------------------------------------------------------------------//
@@ -192,14 +195,18 @@
TEST_CAST(bool)
// Test the implicit conversion only applies to valid types
-fixed_int8_t to_fixed_int8_t__from_svuint8_t(svuint8_t x) { return x; } // expected-error {{returning 'svuint8_t' (aka '__SVUint8_t') from a function with incompatible result type 'fixed_int8_t' (aka '__SVInt8_t')}}
-fixed_bool_t to_fixed_bool_t__from_svint32_t(svint32_t x) { return x; } // expected-error {{returning 'svint32_t' (aka '__SVInt32_t') from a function with incompatible result type 'fixed_bool_t' (aka '__SVBool_t')}}
+fixed_int8_t to_fixed_int8_t__from_svuint8_t(svuint8_t x) { return x; } // expected-error-re {{returning 'svuint8_t' (aka '__SVUint8_t') from a function with incompatible result type 'fixed_int8_t' (vector of {{[0-9]+}} 'signed char' values)}}
+fixed_bool_t to_fixed_bool_t__from_svint32_t(svint32_t x) { return x; } // expected-error-re {{returning 'svint32_t' (aka '__SVInt32_t') from a function with incompatible result type 'fixed_bool_t' (vector of {{[0-9]+}} 'unsigned char' values)}}
+
+// Test conversion between predicate and uint8 is invalid, both have the same
+// memory representation.
+fixed_bool_t to_fixed_bool_t__from_svuint8_t(svuint8_t x) { return x; } // expected-error-re {{returning 'svuint8_t' (aka '__SVUint8_t') from a function with incompatible result type 'fixed_bool_t' (vector of {{[0-9]+}} 'unsigned char' values)}}
// Test the implicit conversion only applies to fixed-length types
typedef signed int vSInt32 __attribute__((__vector_size__(16)));
-svint32_t to_svint32_t_from_gnut(vSInt32 x) { return x; } // expected-error {{returning 'vSInt32' (vector of 4 'int' values) from a function with incompatible result type 'svint32_t' (aka '__SVInt32_t')}}
+svint32_t to_svint32_t_from_gnut(vSInt32 x) { return x; } // expected-error-re {{returning 'vSInt32' (vector of {{[0-9]+}} 'int' values) from a function with incompatible result type 'svint32_t' (aka '__SVInt32_t')}}
-vSInt32 to_gnut_from_svint32_t(svint32_t x) { return x; } // expected-error {{returning 'svint32_t' (aka '__SVInt32_t') from a function with incompatible result type 'vSInt32' (vector of 4 'int' values)}}
+vSInt32 to_gnut_from_svint32_t(svint32_t x) { return x; } // expected-error-re {{returning 'svint32_t' (aka '__SVInt32_t') from a function with incompatible result type 'vSInt32' (vector of {{[0-9]+}} 'int' values)}}
// --------------------------------------------------------------------------//
// Test the scalable and fixed-length types can be used interchangeably
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -2305,7 +2305,7 @@
return QualType();
}
- if (T->isSizelessType() && !T->isVLST()) {
+ if (T->isSizelessType()) {
Diag(Loc, diag::err_array_incomplete_or_sizeless_type) << 1 << T;
return QualType();
}
@@ -7760,14 +7760,10 @@
/// HandleArmSveVectorBitsTypeAttr - The "arm_sve_vector_bits" attribute is
/// used to create fixed-length versions of sizeless SVE types defined by
/// the ACLE, such as svint32_t and svbool_t.
-static void HandleArmSveVectorBitsTypeAttr(TypeProcessingState &State,
- QualType &CurType,
- ParsedAttr &Attr) {
- Sema &S = State.getSema();
- ASTContext &Ctx = S.Context;
-
+static void HandleArmSveVectorBitsTypeAttr(QualType &CurType, ParsedAttr &Attr,
+ Sema &S) {
// Target must have SVE.
- if (!Ctx.getTargetInfo().hasFeature("sve")) {
+ if (!S.Context.getTargetInfo().hasFeature("sve")) {
S.Diag(Attr.getLoc(), diag::err_attribute_unsupported) << Attr;
Attr.setInvalid();
return;
@@ -7812,8 +7808,18 @@
return;
}
- auto *A = ::new (Ctx) ArmSveVectorBitsAttr(Ctx, Attr, VecSize);
- CurType = State.getAttributedType(A, CurType, CurType);
+ const auto *BT = CurType->castAs<BuiltinType>();
+
+ QualType EltType = CurType->getSveEltType(S.Context);
+ unsigned TypeSize = S.Context.getTypeSize(EltType);
+ VectorType::VectorKind VecKind = VectorType::SveFixedLengthDataVector;
+ if (BT->getKind() == BuiltinType::SveBool) {
+ // Predicates are represented as i8
+ VecSize /= S.Context.getCharWidth() * S.Context.getCharWidth();
+ VecKind = VectorType::SveFixedLengthPredicateVector;
+ } else
+ VecSize /= TypeSize;
+ CurType = S.Context.getVectorType(EltType, VecSize, VecKind);
}
static void HandleArmMveStrictPolymorphismAttr(TypeProcessingState &State,
@@ -8084,7 +8090,7 @@
attr.setUsedAsTypeAttr();
break;
case ParsedAttr::AT_ArmSveVectorBits:
- HandleArmSveVectorBitsTypeAttr(state, type, attr);
+ HandleArmSveVectorBitsTypeAttr(type, attr, state.getSema());
attr.setUsedAsTypeAttr();
break;
case ParsedAttr::AT_ArmMveStrictPolymorphism: {
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -137,6 +137,7 @@
ICR_Conversion,
ICR_Conversion,
ICR_Conversion,
+ ICR_Conversion,
ICR_OCL_Scalar_Widening,
ICR_Complex_Real_Conversion,
ICR_Conversion,
@@ -174,6 +175,7 @@
"Compatible-types conversion",
"Derived-to-base conversion",
"Vector conversion",
+ "SVE Vector conversion",
"Vector splat",
"Complex-real conversion",
"Block Pointer conversion",
@@ -1650,6 +1652,13 @@
}
}
+ if (ToType->isSizelessBuiltinType() || FromType->isSizelessBuiltinType()) {
+ if (S.Context.areCompatibleSveTypes(FromType, ToType)) {
+ ICK = ICK_SVE_Vector_Conversion;
+ return true;
+ }
+ }
+
// We can perform the conversion between vector types in the following cases:
// 1)vector types are equivalent AltiVec and GCC vector types
// 2)lax vector conversions are permitted and the vector types are of the
@@ -4104,6 +4113,20 @@
: ImplicitConversionSequence::Worse;
}
+ if (SCS1.Second == ICK_SVE_Vector_Conversion &&
+ SCS2.Second == ICK_SVE_Vector_Conversion) {
+ bool SCS1IsCompatibleSVEVectorConversion =
+ S.Context.areCompatibleSveTypes(SCS1.getFromType(), SCS1.getToType(2));
+ bool SCS2IsCompatibleSVEVectorConversion =
+ S.Context.areCompatibleSveTypes(SCS2.getFromType(), SCS2.getToType(2));
+
+ if (SCS1IsCompatibleSVEVectorConversion !=
+ SCS2IsCompatibleSVEVectorConversion)
+ return SCS1IsCompatibleSVEVectorConversion
+ ? ImplicitConversionSequence::Better
+ : ImplicitConversionSequence::Worse;
+ }
+
return ImplicitConversionSequence::Indistinguishable;
}
@@ -5524,6 +5547,7 @@
case ICK_Compatible_Conversion:
case ICK_Derived_To_Base:
case ICK_Vector_Conversion:
+ case ICK_SVE_Vector_Conversion:
case ICK_Vector_Splat:
case ICK_Complex_Real:
case ICK_Block_Pointer_Conversion:
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -4325,6 +4325,12 @@
VK_RValue, /*BasePath=*/nullptr, CCK).get();
break;
+ case ICK_SVE_Vector_Conversion:
+ From = ImpCastExprToType(From, ToType, CK_BitCast, VK_RValue,
+ /*BasePath=*/nullptr, CCK)
+ .get();
+ break;
+
case ICK_Vector_Splat: {
// Vector splat from any arithmetic type to a vector.
Expr *Elem = prepareVectorSplat(ToType, From).get();
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -9010,6 +9010,15 @@
}
}
+ if ((LHSType->isSizelessBuiltinType() && RHSType->isVectorType()) ||
+ (LHSType->isVectorType() && RHSType->isSizelessBuiltinType())) {
+ // Allow assignments between fixed-length and sizeless SVE vectors.
+ if (Context.areCompatibleSveTypes(LHSType, RHSType)) {
+ Kind = CK_BitCast;
+ return Compatible;
+ }
+ }
+
return Incompatible;
}
@@ -9900,6 +9909,22 @@
// Okay, the expression is invalid.
+ // Returns true if the operands are SVE VLA and VLS types.
+ auto IsSveConversion = [](QualType &FirstType, QualType &SecondType) {
+ const VectorType *VecType = SecondType->getAs<VectorType>();
+ return FirstType->isSizelessBuiltinType() && VecType &&
+ (VecType->getVectorKind() == VectorType::SveFixedLengthDataVector ||
+ VecType->getVectorKind() ==
+ VectorType::SveFixedLengthPredicateVector);
+ };
+
+ // If there's a sizeless and fixed-length operand, diagnose that.
+ if (IsSveConversion(LHSType, RHSType) || IsSveConversion(RHSType, LHSType)) {
+ Diag(Loc, diag::err_typecheck_vector_not_convertable_sizeless)
+ << LHSType << RHSType;
+ return QualType();
+ }
+
// If there's a non-vector, non-real operand, diagnose that.
if ((!RHSVecType && !RHSType->isRealType()) ||
(!LHSVecType && !LHSType->isRealType())) {
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -8032,7 +8032,7 @@
return;
}
- if (!NewVD->hasLocalStorage() && T->isSizelessType() && !T->isVLST()) {
+ if (!NewVD->hasLocalStorage() && T->isSizelessType()) {
Diag(NewVD->getLocation(), diag::err_sizeless_nonlocal) << T;
NewVD->setInvalidDecl();
return;
Index: clang/lib/AST/TypePrinter.cpp
===================================================================
--- clang/lib/AST/TypePrinter.cpp
+++ clang/lib/AST/TypePrinter.cpp
@@ -655,6 +655,24 @@
printBefore(T->getElementType(), OS);
break;
}
+ case VectorType::SveFixedLengthDataVector:
+ case VectorType::SveFixedLengthPredicateVector:
+ // FIXME: We prefer to print the size directly here, but have no way
+ // to get the size of the type.
+ OS << "__attribute__((__arm_sve_vector_bits__(";
+
+ if (T->getVectorKind() == VectorType::SveFixedLengthPredicateVector)
+ // Predicates take a bit per byte of the vector size, multiply by 8 to
+ // get the number of bits passed to the attribute.
+ OS << T->getNumElements() * 8;
+ else
+ OS << T->getNumElements();
+
+ OS << " * sizeof(";
+ print(T->getElementType(), OS, StringRef());
+ // Multiply by 8 for the number of bits.
+ OS << ") * 8))) ";
+ printBefore(T->getElementType(), OS);
}
}
@@ -702,6 +720,24 @@
printBefore(T->getElementType(), OS);
break;
}
+ case VectorType::SveFixedLengthDataVector:
+ case VectorType::SveFixedLengthPredicateVector:
+ // FIXME: We prefer to print the size directly here, but have no way
+ // to get the size of the type.
+ OS << "__attribute__((__arm_sve_vector_bits__(";
+ if (T->getSizeExpr()) {
+ T->getSizeExpr()->printPretty(OS, nullptr, Policy);
+ if (T->getVectorKind() == VectorType::SveFixedLengthPredicateVector)
+ // Predicates take a bit per byte of the vector size, multiply by 8 to
+ // get the number of bits passed to the attribute.
+ OS << " * 8";
+ OS << " * sizeof(";
+ print(T->getElementType(), OS, StringRef());
+ // Multiply by 8 for the number of bits.
+ OS << ") * 8";
+ }
+ OS << "))) ";
+ printBefore(T->getElementType(), OS);
}
}
@@ -1634,9 +1670,6 @@
case attr::ArmMveStrictPolymorphism:
OS << "__clang_arm_mve_strict_polymorphism";
break;
- case attr::ArmSveVectorBits:
- OS << "arm_sve_vector_bits";
- break;
}
OS << "))";
}
Index: clang/lib/AST/Type.cpp
===================================================================
--- clang/lib/AST/Type.cpp
+++ clang/lib/AST/Type.cpp
@@ -2313,11 +2313,42 @@
return false;
}
-bool Type::isVLST() const {
- if (!isVLSTBuiltinType())
- return false;
+QualType Type::getSveEltType(const ASTContext &Ctx) const {
+ assert(isVLSTBuiltinType() && "unsupported type!");
- return hasAttr(attr::ArmSveVectorBits);
+ const BuiltinType *BTy = getAs<BuiltinType>();
+ switch (BTy->getKind()) {
+ default:
+ llvm_unreachable("Unknown builtin SVE type!");
+ case BuiltinType::SveInt8:
+ return Ctx.SignedCharTy;
+ case BuiltinType::SveUint8:
+ case BuiltinType::SveBool:
+ // Represent predicates as i8 rather than i1 to avoid any layout issues.
+ // The type is bitcasted to a scalable predicate type when casting between
+ // scalable and fixed-length vectors.
+ return Ctx.UnsignedCharTy;
+ case BuiltinType::SveInt16:
+ return Ctx.ShortTy;
+ case BuiltinType::SveUint16:
+ return Ctx.UnsignedShortTy;
+ case BuiltinType::SveInt32:
+ return Ctx.IntTy;
+ case BuiltinType::SveUint32:
+ return Ctx.UnsignedIntTy;
+ case BuiltinType::SveInt64:
+ return Ctx.LongTy;
+ case BuiltinType::SveUint64:
+ return Ctx.UnsignedLongTy;
+ case BuiltinType::SveFloat16:
+ return Ctx.Float16Ty;
+ case BuiltinType::SveBFloat16:
+ return Ctx.BFloat16Ty;
+ case BuiltinType::SveFloat32:
+ return Ctx.FloatTy;
+ case BuiltinType::SveFloat64:
+ return Ctx.DoubleTy;
+ }
}
bool QualType::isPODType(const ASTContext &Context) const {
Index: clang/lib/AST/TextNodeDumper.cpp
===================================================================
--- clang/lib/AST/TextNodeDumper.cpp
+++ clang/lib/AST/TextNodeDumper.cpp
@@ -1408,6 +1408,12 @@
case VectorType::NeonPolyVector:
OS << " neon poly";
break;
+ case VectorType::SveFixedLengthDataVector:
+ OS << " fixed-length sve data vector";
+ break;
+ case VectorType::SveFixedLengthPredicateVector:
+ OS << " fixed-length sve predicate vector";
+ break;
}
OS << " " << T->getNumElements();
}
Index: clang/lib/AST/JSONNodeDumper.cpp
===================================================================
--- clang/lib/AST/JSONNodeDumper.cpp
+++ clang/lib/AST/JSONNodeDumper.cpp
@@ -616,6 +616,12 @@
case VectorType::NeonPolyVector:
JOS.attribute("vectorKind", "neon poly");
break;
+ case VectorType::SveFixedLengthDataVector:
+ JOS.attribute("vectorKind", "fixed-length sve data vector");
+ break;
+ case VectorType::SveFixedLengthPredicateVector:
+ JOS.attribute("vectorKind", "fixed-length sve predicate vector");
+ break;
}
}
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -1871,50 +1871,6 @@
return TI;
}
-static unsigned getSveVectorWidth(const Type *T) {
- // Get the vector size from the 'arm_sve_vector_bits' attribute via the
- // AttributedTypeLoc associated with the typedef decl.
- if (const auto *TT = T->getAs<TypedefType>()) {
- const TypedefNameDecl *Typedef = TT->getDecl();
- TypeSourceInfo *TInfo = Typedef->getTypeSourceInfo();
- TypeLoc TL = TInfo->getTypeLoc();
- if (AttributedTypeLoc ATL = TL.getAs<AttributedTypeLoc>())
- if (const auto *Attr = ATL.getAttrAs<ArmSveVectorBitsAttr>())
- return Attr->getNumBits();
- }
-
- llvm_unreachable("bad 'arm_sve_vector_bits' attribute!");
-}
-
-static unsigned getSvePredWidth(const ASTContext &Context, const Type *T) {
- return getSveVectorWidth(T) / Context.getCharWidth();
-}
-
-unsigned ASTContext::getBitwidthForAttributedSveType(const Type *T) const {
- assert(T->isVLST() &&
- "getBitwidthForAttributedSveType called for non-attributed type!");
-
- switch (T->castAs<BuiltinType>()->getKind()) {
- default:
- llvm_unreachable("unknown builtin type!");
- case BuiltinType::SveInt8:
- case BuiltinType::SveInt16:
- case BuiltinType::SveInt32:
- case BuiltinType::SveInt64:
- case BuiltinType::SveUint8:
- case BuiltinType::SveUint16:
- case BuiltinType::SveUint32:
- case BuiltinType::SveUint64:
- case BuiltinType::SveFloat16:
- case BuiltinType::SveFloat32:
- case BuiltinType::SveFloat64:
- case BuiltinType::SveBFloat16:
- return getSveVectorWidth(T);
- case BuiltinType::SveBool:
- return getSvePredWidth(*this, T);
- }
-}
-
/// getTypeInfoImpl - Return the size of the specified type, in bits. This
/// method does not work on incomplete types.
///
@@ -1981,6 +1937,13 @@
uint64_t TargetVectorAlign = Target->getMaxVectorAlign();
if (TargetVectorAlign && TargetVectorAlign < Align)
Align = TargetVectorAlign;
+ // Adjust the alignment for fixed-length SVE vectors. This is important for
+ // non-power-of-2 vector lengths.
+ if (VT->getVectorKind() == VectorType::SveFixedLengthDataVector)
+ Align = 128;
+ // Adjust the alignment for fixed-length SVE predicates.
+ if (VT->getVectorKind() == VectorType::SveFixedLengthPredicateVector)
+ Align = 16;
break;
}
@@ -2319,10 +2282,7 @@
Align = Info.Align;
AlignIsRequired = Info.AlignIsRequired;
}
- if (T->isVLST())
- Width = getBitwidthForAttributedSveType(T);
- else
- Width = Info.Width;
+ Width = Info.Width;
break;
}
@@ -8427,6 +8387,31 @@
return false;
}
+bool ASTContext::areCompatibleSveTypes(QualType FirstType,
+ QualType SecondType) {
+ assert(((FirstType->isSizelessBuiltinType() && SecondType->isVectorType()) ||
+ (FirstType->isVectorType() && SecondType->isSizelessBuiltinType())) &&
+ "Expected SVE builtin type and vector type!");
+
+ auto IsValidCast = [&](QualType FirstType, QualType SecondType) {
+ if (const auto *BT = FirstType->getAs<BuiltinType>()) {
+ if (const auto *VT = SecondType->getAs<VectorType>()) {
+ // Predicates have the same representation as uint8 so we also have to
+ // check the kind to make these types incompatible.
+ if (VT->getVectorKind() == VectorType::SveFixedLengthPredicateVector)
+ return BT->getKind() == BuiltinType::SveBool;
+ else if (VT->getVectorKind() == VectorType::SveFixedLengthDataVector)
+ return VT->getElementType().getCanonicalType() ==
+ FirstType->getSveEltType(*this);
+ }
+ }
+ return false;
+ };
+
+ return IsValidCast(FirstType, SecondType) ||
+ IsValidCast(SecondType, FirstType);
+}
+
bool ASTContext::hasDirectOwnershipQualifier(QualType Ty) const {
while (true) {
// __strong id
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -1997,10 +1997,7 @@
bool RequireCompleteSizedType(SourceLocation Loc, QualType T, unsigned DiagID,
const Ts &... Args) {
SizelessTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...);
- CompleteTypeKind Kind = CompleteTypeKind::Normal;
- if (T->isVLST())
- Kind = CompleteTypeKind::AcceptSizeless;
- return RequireCompleteType(Loc, T, Kind, Diagnoser);
+ return RequireCompleteType(Loc, T, CompleteTypeKind::Normal, Diagnoser);
}
void completeExprArrayBound(Expr *E);
@@ -2018,10 +2015,7 @@
bool RequireCompleteSizedExprType(Expr *E, unsigned DiagID,
const Ts &... Args) {
SizelessTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...);
- CompleteTypeKind Kind = CompleteTypeKind::Normal;
- if (E->getType()->isVLST())
- Kind = CompleteTypeKind::AcceptSizeless;
- return RequireCompleteExprType(E, Kind, Diagnoser);
+ return RequireCompleteExprType(E, CompleteTypeKind::Normal, Diagnoser);
}
bool RequireLiteralType(SourceLocation Loc, QualType T,
Index: clang/include/clang/Sema/Overload.h
===================================================================
--- clang/include/clang/Sema/Overload.h
+++ clang/include/clang/Sema/Overload.h
@@ -160,6 +160,9 @@
/// Vector conversions
ICK_Vector_Conversion,
+ /// Arm SVE Vector conversions
+ ICK_SVE_Vector_Conversion,
+
/// A vector splat from an arithmetic type
ICK_Vector_Splat,
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2924,6 +2924,8 @@
"vector size not an integral multiple of component size">;
def err_attribute_zero_size : Error<"zero %0 size">;
def err_attribute_size_too_large : Error<"%0 size too large">;
+def err_typecheck_vector_not_convertable_sizeless : Error<
+ "cannot convert between fixed-length and sizeless vector (%0 and %1)">;
def err_typecheck_vector_not_convertable_implict_truncation : Error<
"cannot convert between %select{scalar|vector}0 type %1 and vector type"
" %2 as implicit conversion would cause truncation">;
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -1548,6 +1548,8 @@
let Args = [UnsignedArgument<"NumBits">];
let Documentation = [ArmSveVectorBitsDocs];
let PragmaAttributeSupport = 0;
+ // Represented as VectorType instead.
+ let ASTNode = 0;
}
def ArmMveStrictPolymorphism : TypeAttr, TargetSpecificAttr<TargetARM> {
Index: clang/include/clang/AST/Type.h
===================================================================
--- clang/include/clang/AST/Type.h
+++ clang/include/clang/AST/Type.h
@@ -1886,14 +1886,16 @@
bool isSizelessType() const;
bool isSizelessBuiltinType() const;
- /// Determines if this is a vector-length-specific type (VLST), i.e. a
- /// sizeless type with the 'arm_sve_vector_bits' attribute applied.
- bool isVLST() const;
/// Determines if this is a sizeless type supported by the
/// 'arm_sve_vector_bits' type attribute, which can be applied to a single
/// SVE vector or predicate, excluding tuple types such as svint32x4_t.
bool isVLSTBuiltinType() const;
+ /// Returns the representative type for the element of an SVE builtin type.
+ /// This is used to represent fixed-length SVE vectors created with the
+ /// 'arm_sve_vector_bits' type attribute as VectorType.
+ QualType getSveEltType(const ASTContext &Ctx) const;
+
/// Types are partitioned into 3 broad categories (C99 6.2.5p1):
/// object types, function types, and incomplete types.
@@ -3219,7 +3221,12 @@
NeonVector,
/// is ARM Neon polynomial vector
- NeonPolyVector
+ NeonPolyVector,
+
+ /// is AArch64 SVE fixed-length data vector
+ SveFixedLengthDataVector,
+ /// is AArch64 SVE fixed-length predicate vector
+ SveFixedLengthPredicateVector
};
protected:
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -2042,6 +2042,11 @@
/// types.
bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec);
+ /// Return true if the given types are an SVE builtin and a VectorType that
+ /// is a fixed-length representation of the SVE builtin for a specific
+ /// vector-length.
+ bool areCompatibleSveTypes(QualType FirstType, QualType SecondType);
+
/// Return true if the type has been explicitly qualified with ObjC ownership.
/// A type may be implicitly qualified with ownership under ObjC ARC, and in
/// some cases the compiler treats these differently.
@@ -2098,10 +2103,6 @@
return getTypeSizeInCharsIfKnown(QualType(Ty, 0));
}
- /// Returns the bitwidth of \p T, an SVE type attributed with
- /// 'arm_sve_vector_bits'. Should only be called if T->isVLST().
- unsigned getBitwidthForAttributedSveType(const Type *T) const;
-
/// Return the ABI-specified alignment of a (complete) type \p T, in
/// bits.
unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; }
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits