diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 3abb49312255a..64d4c5547341e 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2486,15 +2486,6 @@ class ASTContext : public RefCountedBase { /// 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 given vector types are lax-compatible SVE vector types, - /// false otherwise. - bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType); - /// Return true if the given types are an RISC-V vector builtin type and a /// VectorType that is a fixed-length representation of the RISC-V vector /// builtin type for a specific vector-length. diff --git a/clang/include/clang/Sema/SemaARM.h b/clang/include/clang/Sema/SemaARM.h index ce79e94ebdd9b..788a7abf5f9c1 100644 --- a/clang/include/clang/Sema/SemaARM.h +++ b/clang/include/clang/Sema/SemaARM.h @@ -82,6 +82,15 @@ class SemaARM : public SemaBase { void handleInterruptSaveFPAttr(Decl *D, const ParsedAttr &AL); void CheckSMEFunctionDefAttributes(const FunctionDecl *FD); + + /// 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 given vector types are lax-compatible SVE vector types, + /// false otherwise. + bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType); }; SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD); diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 4d44f23c0f503..d785b5a5006cc 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -10443,87 +10443,6 @@ bool ASTContext::areCompatibleVectorTypes(QualType FirstVec, return false; } -/// getSVETypeSize - Return SVE vector or predicate register size. -static uint64_t getSVETypeSize(ASTContext &Context, const BuiltinType *Ty) { - assert(Ty->isSveVLSBuiltinType() && "Invalid SVE Type"); - 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, - QualType SecondType) { - auto IsValidCast = [this](QualType FirstType, QualType SecondType) { - if (const auto *BT = FirstType->getAs()) { - if (const auto *VT = SecondType->getAs()) { - // Predicates have the same representation as uint8 so we also have to - // check the kind to make these types incompatible. - if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate) - return BT->getKind() == BuiltinType::SveBool; - else if (VT->getVectorKind() == VectorKind::SveFixedLengthData) - return VT->getElementType().getCanonicalType() == - FirstType->getSveEltType(*this); - else if (VT->getVectorKind() == VectorKind::Generic) - return getTypeSize(SecondType) == getSVETypeSize(*this, BT) && - hasSameType(VT->getElementType(), - getBuiltinVectorTypeInfo(BT).ElementType); - } - } - return false; - }; - - return IsValidCast(FirstType, SecondType) || - IsValidCast(SecondType, FirstType); -} - -bool ASTContext::areLaxCompatibleSveTypes(QualType FirstType, - QualType SecondType) { - auto IsLaxCompatible = [this](QualType FirstType, QualType SecondType) { - const auto *BT = FirstType->getAs(); - if (!BT) - return false; - - const auto *VecTy = SecondType->getAs(); - if (VecTy && (VecTy->getVectorKind() == VectorKind::SveFixedLengthData || - VecTy->getVectorKind() == VectorKind::Generic)) { - const LangOptions::LaxVectorConversionKind LVCKind = - getLangOpts().getLaxVectorConversions(); - - // Can not convert between sve predicates and sve vectors because of - // different size. - if (BT->getKind() == BuiltinType::SveBool && - VecTy->getVectorKind() == VectorKind::SveFixedLengthData) - return false; - - // If __ARM_FEATURE_SVE_BITS != N do not allow GNU vector lax conversion. - // "Whenever __ARM_FEATURE_SVE_BITS==N, GNUT implicitly - // converts to VLAT and VLAT implicitly converts to GNUT." - // ACLE Spec Version 00bet6, 3.7.3.2. Behavior common to vectors and - // predicates. - if (VecTy->getVectorKind() == VectorKind::Generic && - getTypeSize(SecondType) != getSVETypeSize(*this, BT)) - return false; - - // If -flax-vector-conversions=all is specified, the types are - // certainly compatible. - if (LVCKind == LangOptions::LaxVectorConversionKind::All) - return true; - - // If -flax-vector-conversions=integer is specified, the types are - // compatible if the elements are integer types. - if (LVCKind == LangOptions::LaxVectorConversionKind::Integer) - return VecTy->getElementType().getCanonicalType()->isIntegerType() && - FirstType->getSveEltType(*this)->isIntegerType(); - } - - return false; - }; - - return IsLaxCompatible(FirstType, SecondType) || - IsLaxCompatible(SecondType, FirstType); -} - /// getRVVTypeSize - Return RVV vector register size. static uint64_t getRVVTypeSize(ASTContext &Context, const BuiltinType *Ty) { assert(Ty->isRVVVLSBuiltinType() && "Invalid RVV Type"); diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp index e992a1012fde0..f7965ff889bba 100644 --- a/clang/lib/Sema/SemaARM.cpp +++ b/clang/lib/Sema/SemaARM.cpp @@ -1409,4 +1409,88 @@ void SemaARM::CheckSMEFunctionDefAttributes(const FunctionDecl *FD) { } } +/// getSVETypeSize - Return SVE vector or predicate register size. +static uint64_t getSVETypeSize(ASTContext &Context, const BuiltinType *Ty) { + assert(Ty->isSveVLSBuiltinType() && "Invalid SVE Type"); + if (Ty->getKind() == BuiltinType::SveBool || + Ty->getKind() == BuiltinType::SveCount) + return (Context.getLangOpts().VScaleMin * 128) / Context.getCharWidth(); + return Context.getLangOpts().VScaleMin * 128; +} + +bool SemaARM::areCompatibleSveTypes(QualType FirstType, QualType SecondType) { + auto IsValidCast = [this](QualType FirstType, QualType SecondType) { + if (const auto *BT = FirstType->getAs()) { + if (const auto *VT = SecondType->getAs()) { + ASTContext &Context = getASTContext(); + // Predicates have the same representation as uint8 so we also have to + // check the kind to make these types incompatible. + if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate) + return BT->getKind() == BuiltinType::SveBool; + else if (VT->getVectorKind() == VectorKind::SveFixedLengthData) + return VT->getElementType().getCanonicalType() == + FirstType->getSveEltType(Context); + else if (VT->getVectorKind() == VectorKind::Generic) + return Context.getTypeSize(SecondType) == + getSVETypeSize(Context, BT) && + Context.hasSameType( + VT->getElementType(), + Context.getBuiltinVectorTypeInfo(BT).ElementType); + } + } + return false; + }; + + return IsValidCast(FirstType, SecondType) || + IsValidCast(SecondType, FirstType); +} + +bool SemaARM::areLaxCompatibleSveTypes(QualType FirstType, + QualType SecondType) { + auto IsLaxCompatible = [this](QualType FirstType, QualType SecondType) { + const auto *BT = FirstType->getAs(); + if (!BT) + return false; + + const auto *VecTy = SecondType->getAs(); + if (VecTy && (VecTy->getVectorKind() == VectorKind::SveFixedLengthData || + VecTy->getVectorKind() == VectorKind::Generic)) { + const LangOptions::LaxVectorConversionKind LVCKind = + getLangOpts().getLaxVectorConversions(); + ASTContext &Context = getASTContext(); + + // Can not convert between sve predicates and sve vectors because of + // different size. + if (BT->getKind() == BuiltinType::SveBool && + VecTy->getVectorKind() == VectorKind::SveFixedLengthData) + return false; + + // If __ARM_FEATURE_SVE_BITS != N do not allow GNU vector lax conversion. + // "Whenever __ARM_FEATURE_SVE_BITS==N, GNUT implicitly + // converts to VLAT and VLAT implicitly converts to GNUT." + // ACLE Spec Version 00bet6, 3.7.3.2. Behavior common to vectors and + // predicates. + if (VecTy->getVectorKind() == VectorKind::Generic && + Context.getTypeSize(SecondType) != getSVETypeSize(Context, BT)) + return false; + + // If -flax-vector-conversions=all is specified, the types are + // certainly compatible. + if (LVCKind == LangOptions::LaxVectorConversionKind::All) + return true; + + // If -flax-vector-conversions=integer is specified, the types are + // compatible if the elements are integer types. + if (LVCKind == LangOptions::LaxVectorConversionKind::Integer) + return VecTy->getElementType().getCanonicalType()->isIntegerType() && + FirstType->getSveEltType(Context)->isIntegerType(); + } + + return false; + }; + + return IsLaxCompatible(FirstType, SecondType) || + IsLaxCompatible(SecondType, FirstType); +} + } // namespace clang diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 8f8e1ceb7197e..bae4cc67da98f 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -12057,10 +12057,10 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, // Strip vector types. if (isa(Source)) { if (Target->isSveVLSBuiltinType() && - (Context.areCompatibleSveTypes(QualType(Target, 0), - QualType(Source, 0)) || - Context.areLaxCompatibleSveTypes(QualType(Target, 0), - QualType(Source, 0)))) + (ARM().areCompatibleSveTypes(QualType(Target, 0), + QualType(Source, 0)) || + ARM().areLaxCompatibleSveTypes(QualType(Target, 0), + QualType(Source, 0)))) return; if (Target->isRVVVLSBuiltinType() && @@ -12120,10 +12120,10 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, const Type *OriginalTarget = Context.getCanonicalType(T).getTypePtr(); // Handle conversion from scalable to fixed when msve-vector-bits is // specified - if (Context.areCompatibleSveTypes(QualType(OriginalTarget, 0), - QualType(Source, 0)) || - Context.areLaxCompatibleSveTypes(QualType(OriginalTarget, 0), - QualType(Source, 0))) + if (ARM().areCompatibleSveTypes(QualType(OriginalTarget, 0), + QualType(Source, 0)) || + ARM().areLaxCompatibleSveTypes(QualType(OriginalTarget, 0), + QualType(Source, 0))) return; // If the vector cast is cast between two vectors of the same size, it is diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c7abbbd6993de..087db40573ef6 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -51,6 +51,7 @@ #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" +#include "clang/Sema/SemaARM.h" #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaFixItUtils.h" #include "clang/Sema/SemaHLSL.h" @@ -9533,8 +9534,8 @@ AssignConvertType Sema::CheckAssignmentConstraints(QualType LHSType, // Allow assignments between fixed-length and sizeless SVE vectors. if ((LHSType->isSVESizelessBuiltinType() && RHSType->isVectorType()) || (LHSType->isVectorType() && RHSType->isSVESizelessBuiltinType())) - if (Context.areCompatibleSveTypes(LHSType, RHSType) || - Context.areLaxCompatibleSveTypes(LHSType, RHSType)) { + if (ARM().areCompatibleSveTypes(LHSType, RHSType) || + ARM().areLaxCompatibleSveTypes(LHSType, RHSType)) { Kind = CK_BitCast; return AssignConvertType::Compatible; } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 89e86f49a3ca8..4d5964c1a93b0 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -30,6 +30,7 @@ #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Overload.h" +#include "clang/Sema/SemaARM.h" #include "clang/Sema/SemaCUDA.h" #include "clang/Sema/SemaObjC.h" #include "clang/Sema/Template.h" @@ -2180,8 +2181,8 @@ static bool IsVectorConversion(Sema &S, QualType FromType, QualType ToType, if (ToType->isSVESizelessBuiltinType() || FromType->isSVESizelessBuiltinType()) - if (S.Context.areCompatibleSveTypes(FromType, ToType) || - S.Context.areLaxCompatibleSveTypes(FromType, ToType)) { + if (S.ARM().areCompatibleSveTypes(FromType, ToType) || + S.ARM().areLaxCompatibleSveTypes(FromType, ToType)) { ICK = ICK_SVE_Vector_Conversion; return true; } @@ -4735,9 +4736,9 @@ CompareStandardConversionSequences(Sema &S, SourceLocation Loc, if (SCS1.Second == ICK_SVE_Vector_Conversion && SCS2.Second == ICK_SVE_Vector_Conversion) { bool SCS1IsCompatibleSVEVectorConversion = - S.Context.areCompatibleSveTypes(SCS1.getFromType(), SCS1.getToType(2)); + S.ARM().areCompatibleSveTypes(SCS1.getFromType(), SCS1.getToType(2)); bool SCS2IsCompatibleSVEVectorConversion = - S.Context.areCompatibleSveTypes(SCS2.getFromType(), SCS2.getToType(2)); + S.ARM().areCompatibleSveTypes(SCS2.getFromType(), SCS2.getToType(2)); if (SCS1IsCompatibleSVEVectorConversion != SCS2IsCompatibleSVEVectorConversion)