Author: Paul Walker
Date: 2026-10-29T13:51:42Z
New Revision: 1efaf204d16c6cc911cb35d86362906277c9cf54

URL: 
https://github.com/llvm/llvm-project/commit/1efaf204d16c6cc911cb35d86362906277c9cf54
DIFF: 
https://github.com/llvm/llvm-project/commit/1efaf204d16c6cc911cb35d86362906277c9cf54.diff

LOG: [Clang][AArch64] Reject attempts to cast to multivector SVE ACLE types. 
(#236116)

Fixes https://github.com/llvm/llvm-project/issues/234170.

Added: 
    

Modified: 
    clang/lib/AST/Type.cpp
    clang/lib/Sema/SemaARM.cpp
    clang/test/Sema/aarch64-sve-lax-vector-conversions.c
    clang/test/Sema/attr-arm-sve-vector-bits.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 4c5f2f60a90005..9fc657168abe4a 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2842,8 +2842,6 @@ bool Type::isSveVLSBuiltinType() const {
     case BuiltinType::SveFloat64:
     case BuiltinType::SveBFloat16:
     case BuiltinType::SveBool:
-    case BuiltinType::SveBoolx2:
-    case BuiltinType::SveBoolx4:
     case BuiltinType::SveMFloat8:
       return true;
     default:

diff  --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp
index 9938e187f7aad5..6ca3c45f47b777 100644
--- a/clang/lib/Sema/SemaARM.cpp
+++ b/clang/lib/Sema/SemaARM.cpp
@@ -1726,25 +1726,32 @@ bool SemaARM::areCompatibleSveTypes(QualType FirstType, 
QualType SecondType) {
   }
 
   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.
-        ASTContext &Context = getASTContext();
-        if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate)
-          return BT->getKind() == BuiltinType::SveBool;
-        else if (VT->getVectorKind() == VectorKind::SveFixedLengthData)
-          return VT->getElementType().getCanonicalType() ==
-                     FirstType->getSveEltType(Context) &&
-                 BT->getKind() != BuiltinType::SveBool;
-        else if (VT->getVectorKind() == VectorKind::Generic)
-          return Context.getTypeSize(SecondType) ==
-                     getSVETypeSize(Context, BT, IsStreaming) &&
-                 Context.hasSameType(
-                     VT->getElementType(),
-                     Context.getBuiltinVectorTypeInfo(BT).ElementType);
-      }
-    }
+    const auto *BT = FirstType->getAs<BuiltinType>();
+    if (!BT || !BT->isSveVLSBuiltinType())
+      return false;
+
+    const auto *VT = SecondType->getAs<VectorType>();
+    if (!VT)
+      return false;
+
+    // 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;
+
+    ASTContext &Context = getASTContext();
+    if (VT->getVectorKind() == VectorKind::SveFixedLengthData)
+      return VT->getElementType().getCanonicalType() ==
+                 FirstType->getSveEltType(Context) &&
+             BT->getKind() != BuiltinType::SveBool;
+
+    if (VT->getVectorKind() == VectorKind::Generic)
+      return Context.getTypeSize(SecondType) ==
+                 getSVETypeSize(Context, BT, IsStreaming) &&
+             Context.hasSameType(
+                 VT->getElementType(),
+                 Context.getBuiltinVectorTypeInfo(BT).ElementType);
+
     return false;
   };
 
@@ -1772,7 +1779,7 @@ bool SemaARM::areLaxCompatibleSveTypes(QualType FirstType,
 
   auto IsLaxCompatible = [&](QualType FirstType, QualType SecondType) {
     const auto *BT = FirstType->getAs<BuiltinType>();
-    if (!BT)
+    if (!BT || !BT->isSveVLSBuiltinType())
       return false;
 
     const auto *VecTy = SecondType->getAs<VectorType>();

diff  --git a/clang/test/Sema/aarch64-sve-lax-vector-conversions.c 
b/clang/test/Sema/aarch64-sve-lax-vector-conversions.c
index c3aae93404ac98..f121813516699b 100644
--- a/clang/test/Sema/aarch64-sve-lax-vector-conversions.c
+++ b/clang/test/Sema/aarch64-sve-lax-vector-conversions.c
@@ -2,20 +2,17 @@
 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve 
-mvscale-min=4 -mvscale-max=4 -flax-vector-conversions=integer -ffreestanding 
-fsyntax-only -verify=lax-vector-integer %s
 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve 
-mvscale-min=4 -mvscale-max=4 -flax-vector-conversions=all -ffreestanding 
-fsyntax-only -verify=lax-vector-all %s
 
-// lax-vector-all-no-diagnostics
-
-// REQUIRES: aarch64-registered-target || arm-registered-target
+// REQUIRES: aarch64-registered-target
 
 #include <arm_sve.h>
 
 #define N __ARM_FEATURE_SVE_BITS
-#define SVE_FIXED_ATTR __attribute__((arm_sve_vector_bits(N)))
-#define GNU_FIXED_ATTR __attribute__((vector_size(N / 8)))
 
-typedef svfloat32_t sve_fixed_float32_t SVE_FIXED_ATTR;
-typedef svint32_t sve_fixed_int32_t SVE_FIXED_ATTR;
-typedef float gnu_fixed_float32_t GNU_FIXED_ATTR;
-typedef int gnu_fixed_int32_t GNU_FIXED_ATTR;
+typedef svfloat32_t sve_fixed_float32_t 
__attribute__((arm_sve_vector_bits(N)));
+typedef svint32_t sve_fixed_int32_t     
__attribute__((arm_sve_vector_bits(N)));
+typedef float gnu_fixed_float32_t       __attribute__((vector_size(N / 8)));
+typedef int gnu_fixed_int32_t           __attribute__((vector_size(N / 8)));
+typedef float gnu_fixed_float32x2_t     __attribute__((vector_size((N * 2) / 
8)));
 
 void sve_allowed_with_integer_lax_conversions() {
   sve_fixed_int32_t fi32;
@@ -68,3 +65,18 @@ void gnu_allowed_with_all_lax_conversions() {
   // lax-vector-none-error@-1 {{assigning to 'svfloat64_t' (aka 
'__SVFloat64_t') from incompatible type}}
   // lax-vector-integer-error@-2 {{assigning to 'svfloat64_t' (aka 
'__SVFloat64_t') from incompatible type}}
 }
+
+void gnu_dissallow_multivector_conversions() {
+  svint64x2_t sf64;
+  gnu_fixed_float32x2_t ff32;
+
+  sf64 = ff32;
+  // lax-vector-none-error@-1 {{assigning to 'svint64x2_t' (aka 
'__clang_svint64x2_t') from incompatible type}}
+  // lax-vector-integer-error@-2 {{assigning to 'svint64x2_t' (aka 
'__clang_svint64x2_t') from incompatible type}}
+  // lax-vector-all-error@-3 {{assigning to 'svint64x2_t' (aka 
'__clang_svint64x2_t') from incompatible type}}
+
+  ff32 = sf64;
+  // lax-vector-none-error@-1 {{assigning to 'gnu_fixed_float32x2_t' (vector 
of 32 'float' values) from incompatible type}}
+  // lax-vector-integer-error@-2 {{assigning to 'gnu_fixed_float32x2_t' 
(vector of 32 'float' values) from incompatible type}}
+  // lax-vector-all-error@-3 {{assigning to 'gnu_fixed_float32x2_t' (vector of 
32 'float' values) from incompatible type}}
+}

diff  --git a/clang/test/Sema/attr-arm-sve-vector-bits.c 
b/clang/test/Sema/attr-arm-sve-vector-bits.c
index 1f6b01aa87669e..a76c80268a7e92 100644
--- a/clang/test/Sema/attr-arm-sve-vector-bits.c
+++ b/clang/test/Sema/attr-arm-sve-vector-bits.c
@@ -76,6 +76,8 @@ typedef svint8_t non_int_size2 
__attribute__((arm_sve_vector_bits("256"))); // e
 
 typedef __clang_svint8x2_t svint8x2_t;
 typedef __clang_svfloat32x3_t svfloat32x3_t;
+typedef __clang_svboolx2_t svboolx2_t;
+typedef __clang_svboolx4_t svboolx4_t;
 
 // Attribute must be attached to a single SVE vector or predicate type.
 typedef void *badtype1 __attribute__((arm_sve_vector_bits(N)));         // 
expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 'void 
*'}}
@@ -83,6 +85,8 @@ typedef int badtype2 __attribute__((arm_sve_vector_bits(N))); 
          // expec
 typedef float badtype3 __attribute__((arm_sve_vector_bits(N)));         // 
expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 
'float'}}
 typedef svint8x2_t badtype4 __attribute__((arm_sve_vector_bits(N)));    // 
expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 
'svint8x2_t' (aka '__clang_svint8x2_t')}}
 typedef svfloat32x3_t badtype5 __attribute__((arm_sve_vector_bits(N))); // 
expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 
'svfloat32x3_t' (aka '__clang_svfloat32x3_t')}}
+typedef svboolx2_t badtype6 __attribute__((arm_sve_vector_bits(N)));    // 
expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 
'svboolx2_t' (aka '__clang_svboolx2_t')}}
+typedef svboolx4_t badtype7 __attribute__((arm_sve_vector_bits(N)));    // 
expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 
'svboolx4_t' (aka '__clang_svboolx4_t')}}
 
 // Attribute only applies to typedefs.
 svint8_t non_typedef_type __attribute__((arm_sve_vector_bits(N)));  // 
expected-error {{'arm_sve_vector_bits' attribute only applies to typedefs}}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to