Skip to content

Conversation

@paulwalker-arm
Copy link
Collaborator

As is done for other targets, I've moved the target type checking code into SemaARM and migrated existing uses.

Fixes #155736

@llvmbot llvmbot added clang Clang issues not falling into any other category backend:ARM backend:AArch64 clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Nov 14, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 14, 2025

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-backend-aarch64

Author: Paul Walker (paulwalker-arm)

Changes

As is done for other targets, I've moved the target type checking code into SemaARM and migrated existing uses.

Fixes #155736


Full diff: https://github.com/llvm/llvm-project/pull/168097.diff

5 Files Affected:

  • (modified) clang/include/clang/Sema/SemaARM.h (+3)
  • (modified) clang/lib/Sema/Sema.cpp (+2-8)
  • (modified) clang/lib/Sema/SemaARM.cpp (+20)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+4-14)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+8)
diff --git a/clang/include/clang/Sema/SemaARM.h b/clang/include/clang/Sema/SemaARM.h
index 104992e8826c3..1e8941a381dc5 100644
--- a/clang/include/clang/Sema/SemaARM.h
+++ b/clang/include/clang/Sema/SemaARM.h
@@ -96,6 +96,9 @@ class SemaARM : public SemaBase {
   bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params,
                              SmallVectorImpl<SourceLocation> &Locs,
                              SmallVectorImpl<SmallString<64>> &NewParams);
+  bool checkSVETypeSupport(QualType Ty, SourceLocation Loc,
+                           const FunctionDecl *FD,
+                           const llvm::StringMap<bool> &FeatureMap);
 };
 
 SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD);
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 46addea232b03..1541b2cc95d8c 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -2254,16 +2254,10 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) {
     }
 
     // Don't allow SVE types in functions without a SVE target.
-    if (Ty->isSVESizelessBuiltinType() && FD && !FD->getType().isNull()) {
+    if (Ty->isSVESizelessBuiltinType() && FD) {
       llvm::StringMap<bool> CallerFeatureMap;
       Context.getFunctionFeatureMap(CallerFeatureMap, FD);
-      if (!Builtin::evaluateRequiredTargetFeatures("sve", CallerFeatureMap)) {
-        if (!Builtin::evaluateRequiredTargetFeatures("sme", CallerFeatureMap))
-          Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
-        else if (!IsArmStreamingFunction(FD,
-                                         /*IncludeLocallyStreaming=*/true))
-          Diag(Loc, diag::err_sve_vector_in_non_streaming_function) << Ty;
-      }
+      ARM().checkSVETypeSupport(Ty, Loc, FD, CallerFeatureMap);
     }
 
     if (auto *VT = Ty->getAs<VectorType>();
diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp
index ab37394cd5f98..0a96f4f3bd170 100644
--- a/clang/lib/Sema/SemaARM.cpp
+++ b/clang/lib/Sema/SemaARM.cpp
@@ -1685,4 +1685,24 @@ bool SemaARM::checkTargetClonesAttr(
   return false;
 }
 
+bool SemaARM::checkSVETypeSupport(QualType Ty, SourceLocation Loc,
+                                  const FunctionDecl *FD,
+                                  const llvm::StringMap<bool> &FeatureMap) {
+  if (!Ty->isSVESizelessBuiltinType())
+    return false;
+
+  if (FeatureMap.lookup("sve"))
+    return false;
+
+  // No SVE environment available.
+  if (!FeatureMap.lookup("sme"))
+    return Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
+
+  // SVE environment only available to streaming functions.
+  if (FD && !FD->getType().isNull() &&
+      !IsArmStreamingFunction(FD, /*IncludeLocallyStreaming=*/true))
+    return Diag(Loc, diag::err_sve_vector_in_non_streaming_function) << Ty;
+
+  return false;
+}
 } // namespace clang
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 086dd8ba1c670..cef1a5c4b24f6 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9125,20 +9125,10 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
     const FunctionDecl *FD = cast<FunctionDecl>(CurContext);
     llvm::StringMap<bool> CallerFeatureMap;
     Context.getFunctionFeatureMap(CallerFeatureMap, FD);
-
-    if (!Builtin::evaluateRequiredTargetFeatures("sve", CallerFeatureMap)) {
-      if (!Builtin::evaluateRequiredTargetFeatures("sme", CallerFeatureMap)) {
-        Diag(NewVD->getLocation(), diag::err_sve_vector_in_non_sve_target) << T;
-        NewVD->setInvalidDecl();
-        return;
-      } else if (!IsArmStreamingFunction(FD,
-                                         /*IncludeLocallyStreaming=*/true)) {
-        Diag(NewVD->getLocation(),
-             diag::err_sve_vector_in_non_streaming_function)
-            << T;
-        NewVD->setInvalidDecl();
-        return;
-      }
+    if (ARM().checkSVETypeSupport(T, NewVD->getLocation(), FD,
+                                  CallerFeatureMap)) {
+      NewVD->setInvalidDecl();
+      return;
     }
   }
 
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 2159a0dc2a5d7..b17402ecc2e68 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4189,6 +4189,14 @@ static bool CheckVectorElementsTraitOperandType(Sema &S, QualType T,
            << ""
            << "__builtin_vectorelements" << T << ArgRange;
 
+  if (auto *FD = dyn_cast<FunctionDecl>(S.CurContext)) {
+    if (T->isSVESizelessBuiltinType()) {
+      llvm::StringMap<bool> CallerFeatureMap;
+      S.Context.getFunctionFeatureMap(CallerFeatureMap, FD);
+      return S.ARM().checkSVETypeSupport(T, Loc, FD, CallerFeatureMap);
+    }
+  }
+
   return false;
 }
 

@llvmbot
Copy link
Member

llvmbot commented Nov 14, 2025

@llvm/pr-subscribers-backend-arm

Author: Paul Walker (paulwalker-arm)

Changes

As is done for other targets, I've moved the target type checking code into SemaARM and migrated existing uses.

Fixes #155736


Full diff: https://github.com/llvm/llvm-project/pull/168097.diff

5 Files Affected:

  • (modified) clang/include/clang/Sema/SemaARM.h (+3)
  • (modified) clang/lib/Sema/Sema.cpp (+2-8)
  • (modified) clang/lib/Sema/SemaARM.cpp (+20)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+4-14)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+8)
diff --git a/clang/include/clang/Sema/SemaARM.h b/clang/include/clang/Sema/SemaARM.h
index 104992e8826c3..1e8941a381dc5 100644
--- a/clang/include/clang/Sema/SemaARM.h
+++ b/clang/include/clang/Sema/SemaARM.h
@@ -96,6 +96,9 @@ class SemaARM : public SemaBase {
   bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params,
                              SmallVectorImpl<SourceLocation> &Locs,
                              SmallVectorImpl<SmallString<64>> &NewParams);
+  bool checkSVETypeSupport(QualType Ty, SourceLocation Loc,
+                           const FunctionDecl *FD,
+                           const llvm::StringMap<bool> &FeatureMap);
 };
 
 SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD);
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 46addea232b03..1541b2cc95d8c 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -2254,16 +2254,10 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) {
     }
 
     // Don't allow SVE types in functions without a SVE target.
-    if (Ty->isSVESizelessBuiltinType() && FD && !FD->getType().isNull()) {
+    if (Ty->isSVESizelessBuiltinType() && FD) {
       llvm::StringMap<bool> CallerFeatureMap;
       Context.getFunctionFeatureMap(CallerFeatureMap, FD);
-      if (!Builtin::evaluateRequiredTargetFeatures("sve", CallerFeatureMap)) {
-        if (!Builtin::evaluateRequiredTargetFeatures("sme", CallerFeatureMap))
-          Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
-        else if (!IsArmStreamingFunction(FD,
-                                         /*IncludeLocallyStreaming=*/true))
-          Diag(Loc, diag::err_sve_vector_in_non_streaming_function) << Ty;
-      }
+      ARM().checkSVETypeSupport(Ty, Loc, FD, CallerFeatureMap);
     }
 
     if (auto *VT = Ty->getAs<VectorType>();
diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp
index ab37394cd5f98..0a96f4f3bd170 100644
--- a/clang/lib/Sema/SemaARM.cpp
+++ b/clang/lib/Sema/SemaARM.cpp
@@ -1685,4 +1685,24 @@ bool SemaARM::checkTargetClonesAttr(
   return false;
 }
 
+bool SemaARM::checkSVETypeSupport(QualType Ty, SourceLocation Loc,
+                                  const FunctionDecl *FD,
+                                  const llvm::StringMap<bool> &FeatureMap) {
+  if (!Ty->isSVESizelessBuiltinType())
+    return false;
+
+  if (FeatureMap.lookup("sve"))
+    return false;
+
+  // No SVE environment available.
+  if (!FeatureMap.lookup("sme"))
+    return Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
+
+  // SVE environment only available to streaming functions.
+  if (FD && !FD->getType().isNull() &&
+      !IsArmStreamingFunction(FD, /*IncludeLocallyStreaming=*/true))
+    return Diag(Loc, diag::err_sve_vector_in_non_streaming_function) << Ty;
+
+  return false;
+}
 } // namespace clang
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 086dd8ba1c670..cef1a5c4b24f6 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9125,20 +9125,10 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
     const FunctionDecl *FD = cast<FunctionDecl>(CurContext);
     llvm::StringMap<bool> CallerFeatureMap;
     Context.getFunctionFeatureMap(CallerFeatureMap, FD);
-
-    if (!Builtin::evaluateRequiredTargetFeatures("sve", CallerFeatureMap)) {
-      if (!Builtin::evaluateRequiredTargetFeatures("sme", CallerFeatureMap)) {
-        Diag(NewVD->getLocation(), diag::err_sve_vector_in_non_sve_target) << T;
-        NewVD->setInvalidDecl();
-        return;
-      } else if (!IsArmStreamingFunction(FD,
-                                         /*IncludeLocallyStreaming=*/true)) {
-        Diag(NewVD->getLocation(),
-             diag::err_sve_vector_in_non_streaming_function)
-            << T;
-        NewVD->setInvalidDecl();
-        return;
-      }
+    if (ARM().checkSVETypeSupport(T, NewVD->getLocation(), FD,
+                                  CallerFeatureMap)) {
+      NewVD->setInvalidDecl();
+      return;
     }
   }
 
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 2159a0dc2a5d7..b17402ecc2e68 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4189,6 +4189,14 @@ static bool CheckVectorElementsTraitOperandType(Sema &S, QualType T,
            << ""
            << "__builtin_vectorelements" << T << ArgRange;
 
+  if (auto *FD = dyn_cast<FunctionDecl>(S.CurContext)) {
+    if (T->isSVESizelessBuiltinType()) {
+      llvm::StringMap<bool> CallerFeatureMap;
+      S.Context.getFunctionFeatureMap(CallerFeatureMap, FD);
+      return S.ARM().checkSVETypeSupport(T, Loc, FD, CallerFeatureMap);
+    }
+  }
+
   return false;
 }
 

… when SVE is not available.

As is done for other targets, I've moved the target type checking code
into SemaARM and migrated existing uses.

Fixes llvm#155736
@paulwalker-arm paulwalker-arm force-pushed the sve-acle-builtin_vectorelements branch from b29ffcc to 0accf99 Compare November 14, 2025 18:18
Copy link
Collaborator

@labrinea labrinea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, with minor comments

@paulwalker-arm paulwalker-arm merged commit 6bf3249 into llvm:main Nov 25, 2025
10 checks passed
@paulwalker-arm paulwalker-arm deleted the sve-acle-builtin_vectorelements branch November 25, 2025 13:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:AArch64 backend:ARM clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[AArch64][SVE] fatal error: error in backend: Cannot select: 0x4c53a330: i64 = vscale Constant:i64<16>

3 participants