@@ -1409,4 +1409,101 @@ void SemaARM::CheckSMEFunctionDefAttributes(const FunctionDecl *FD) {
14091409 }
14101410}
14111411
1412+ // / getSVETypeSize - Return SVE vector or predicate register size.
1413+ static uint64_t getSVETypeSize (ASTContext &Context, const BuiltinType *Ty,
1414+ bool IsStreaming) {
1415+ assert (Ty->isSveVLSBuiltinType () && " Invalid SVE Type" );
1416+ uint64_t VScale = IsStreaming ? Context.getLangOpts ().VScaleStreamingMin
1417+ : Context.getLangOpts ().VScaleMin ;
1418+ if (Ty->getKind () == BuiltinType::SveBool ||
1419+ Ty->getKind () == BuiltinType::SveCount)
1420+ return (VScale * 128 ) / Context.getCharWidth ();
1421+ return VScale * 128 ;
1422+ }
1423+
1424+ bool SemaARM::areCompatibleSveTypes (QualType FirstType, QualType SecondType) {
1425+ bool IsStreaming = false ;
1426+ if (const FunctionDecl *FD = SemaRef.getCurFunctionDecl (/* AllowLambda=*/ true ))
1427+ if (IsArmStreamingFunction (FD, /* IncludeLocallyStreaming=*/ true ))
1428+ IsStreaming = true ;
1429+ auto IsValidCast = [&](QualType FirstType, QualType SecondType) {
1430+ if (const auto *BT = FirstType->getAs <BuiltinType>()) {
1431+ if (const auto *VT = SecondType->getAs <VectorType>()) {
1432+ // Predicates have the same representation as uint8 so we also have to
1433+ // check the kind to make these types incompatible.
1434+ ASTContext &Context = getASTContext ();
1435+ if (VT->getVectorKind () == VectorKind::SveFixedLengthPredicate)
1436+ return BT->getKind () == BuiltinType::SveBool;
1437+ else if (VT->getVectorKind () == VectorKind::SveFixedLengthData)
1438+ return VT->getElementType ().getCanonicalType () ==
1439+ FirstType->getSveEltType (Context);
1440+ else if (VT->getVectorKind () == VectorKind::Generic)
1441+ return Context.getTypeSize (SecondType) ==
1442+ getSVETypeSize (Context, BT, IsStreaming) &&
1443+ Context.hasSameType (
1444+ VT->getElementType (),
1445+ Context.getBuiltinVectorTypeInfo (BT).ElementType );
1446+ }
1447+ }
1448+ return false ;
1449+ };
1450+
1451+ return IsValidCast (FirstType, SecondType) ||
1452+ IsValidCast (SecondType, FirstType);
1453+ }
1454+
1455+ bool SemaARM::areLaxCompatibleSveTypes (QualType FirstType,
1456+ QualType SecondType) {
1457+ bool IsStreaming = false ;
1458+ if (const FunctionDecl *FD = SemaRef.getCurFunctionDecl (/* AllowLambda=*/ true ))
1459+ if (IsArmStreamingFunction (FD, /* IncludeLocallyStreaming=*/ true ))
1460+ IsStreaming = true ;
1461+
1462+ auto IsLaxCompatible = [&](QualType FirstType, QualType SecondType) {
1463+ const auto *BT = FirstType->getAs <BuiltinType>();
1464+ if (!BT)
1465+ return false ;
1466+
1467+ const auto *VecTy = SecondType->getAs <VectorType>();
1468+ if (VecTy && (VecTy->getVectorKind () == VectorKind::SveFixedLengthData ||
1469+ VecTy->getVectorKind () == VectorKind::Generic)) {
1470+ const LangOptions::LaxVectorConversionKind LVCKind =
1471+ getLangOpts ().getLaxVectorConversions ();
1472+ ASTContext &Context = getASTContext ();
1473+
1474+ // Can not convert between sve predicates and sve vectors because of
1475+ // different size.
1476+ if (BT->getKind () == BuiltinType::SveBool &&
1477+ VecTy->getVectorKind () == VectorKind::SveFixedLengthData)
1478+ return false ;
1479+
1480+ // If __ARM_FEATURE_SVE_BITS != N do not allow GNU vector lax conversion.
1481+ // "Whenever __ARM_FEATURE_SVE_BITS==N, GNUT implicitly
1482+ // converts to VLAT and VLAT implicitly converts to GNUT."
1483+ // ACLE Spec Version 00bet6, 3.7.3.2. Behavior common to vectors and
1484+ // predicates.
1485+ if (VecTy->getVectorKind () == VectorKind::Generic &&
1486+ Context.getTypeSize (SecondType) !=
1487+ getSVETypeSize (Context, BT, IsStreaming))
1488+ return false ;
1489+
1490+ // If -flax-vector-conversions=all is specified, the types are
1491+ // certainly compatible.
1492+ if (LVCKind == LangOptions::LaxVectorConversionKind::All)
1493+ return true ;
1494+
1495+ // If -flax-vector-conversions=integer is specified, the types are
1496+ // compatible if the elements are integer types.
1497+ if (LVCKind == LangOptions::LaxVectorConversionKind::Integer)
1498+ return VecTy->getElementType ().getCanonicalType ()->isIntegerType () &&
1499+ FirstType->getSveEltType (Context)->isIntegerType ();
1500+ }
1501+
1502+ return false ;
1503+ };
1504+
1505+ return IsLaxCompatible (FirstType, SecondType) ||
1506+ IsLaxCompatible (SecondType, FirstType);
1507+ }
1508+
14121509} // namespace clang
0 commit comments