[clang] [Clang] Amend SME attributes with support for ZT0. (PR #77941)

Sander de Smalen via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 15 05:00:53 PST 2024


https://github.com/sdesmalen-arm updated https://github.com/llvm/llvm-project/pull/77941

>From 764e7aaecffb758e7a311c17a189ee605c623246 Mon Sep 17 00:00:00 2001
From: Sander de Smalen <sander.desmalen at arm.com>
Date: Thu, 4 Jan 2024 14:03:04 +0000
Subject: [PATCH 1/2] [Clang] Amend SME attributes with support for ZT0.

This patch builds on top of #76971 and implements support for:
* __arm_new("zt0")
* __arm_in("zt0")
* __arm_out("zt0")
* __arm_inout("zt0")
* __arm_preserves("zt0")

The patch is ready for review but won't be able to land until LLVM
implements support for handling ZT0 state.
---
 clang/include/clang/AST/Type.h                | 15 +++--
 clang/include/clang/Basic/Attr.td             |  3 +
 .../clang/Basic/DiagnosticSemaKinds.td        |  4 ++
 clang/lib/AST/TypePrinter.cpp                 |  8 +++
 clang/lib/CodeGen/CGCall.cpp                  | 10 ++++
 clang/lib/CodeGen/CodeGenModule.cpp           |  2 +
 clang/lib/Sema/SemaChecking.cpp               | 22 +++++++
 clang/lib/Sema/SemaDecl.cpp                   | 11 ++++
 clang/lib/Sema/SemaDeclAttr.cpp               |  8 +++
 clang/lib/Sema/SemaType.cpp                   |  3 +
 .../aarch64-sme2-attrs.cpp                    | 57 +++++++++++++++++++
 ...-sme-func-attrs-without-target-feature.cpp |  2 +
 clang/test/Sema/aarch64-sme-func-attrs.c      | 45 +++++++++++++++
 13 files changed, 186 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGen/aarch64-sme2-intrinsics/aarch64-sme2-attrs.cpp

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index a7efe78591635e..a56401f9da0450 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -4040,9 +4040,12 @@ class FunctionType : public Type {
     // Describes the value of the state using ArmStateValue.
     SME_ZAShift = 2,
     SME_ZAMask = 0b111 << SME_ZAShift,
+    SME_ZT0Shift = 5,
+    SME_ZT0Mask = 0b111 << SME_ZT0Shift,
 
-    SME_AttributeMask = 0b111'111 // We only support maximum 6 bits because of
-                                  // the bitmask in FunctionTypeExtraBitfields.
+    SME_AttributeMask =
+        0b111'111'11 // We can't support more than 8 bits because of
+                     // the bitmask in FunctionTypeExtraBitfields.
   };
 
   enum ArmStateValue : unsigned {
@@ -4057,6 +4060,10 @@ class FunctionType : public Type {
     return (ArmStateValue)((AttrBits & SME_ZAMask) >> SME_ZAShift);
   }
 
+  static ArmStateValue getArmZT0State(unsigned AttrBits) {
+    return (ArmStateValue)((AttrBits & SME_ZT0Mask) >> SME_ZT0Shift);
+  }
+
   /// A simple holder for various uncommon bits which do not fit in
   /// FunctionTypeBitfields. Aligned to alignof(void *) to maintain the
   /// alignment of subsequent objects in TrailingObjects.
@@ -4068,7 +4075,7 @@ class FunctionType : public Type {
 
     /// Any AArch64 SME ACLE type attributes that need to be propagated
     /// on declarations and function pointers.
-    unsigned AArch64SMEAttributes : 6;
+    unsigned AArch64SMEAttributes : 8;
     FunctionTypeExtraBitfields()
         : NumExceptionType(0), AArch64SMEAttributes(SME_NormalFunction) {}
   };
@@ -4253,7 +4260,7 @@ class FunctionProtoType final
     FunctionType::ExtInfo ExtInfo;
     unsigned Variadic : 1;
     unsigned HasTrailingReturn : 1;
-    unsigned AArch64SMEAttributes : 6;
+    unsigned AArch64SMEAttributes : 8;
     Qualifiers TypeQuals;
     RefQualifierKind RefQualifier = RQ_None;
     ExceptionSpecInfo ExceptionSpec;
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index b9ec720dd9e199..174d4e14bfa0ec 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2549,6 +2549,9 @@ def ArmNew : InheritableAttr, TargetSpecificAttr<TargetAArch64> {
     bool isNewZA() const {
       return llvm::is_contained(newArgs(), "za");
     }
+    bool isNewZT0() const {
+      return llvm::is_contained(newArgs(), "zt0");
+    }
   }];
 }
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c50b188a1039ac..cca4a4419d0bf9 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3696,10 +3696,14 @@ def err_sme_call_in_non_sme_target : Error<
   "call to a streaming function requires 'sme'">;
 def err_sme_za_call_no_za_state : Error<
   "call to a shared ZA function requires the caller to have ZA state">;
+def err_sme_zt0_call_no_zt0_state : Error<
+  "call to a shared ZT0 function requires the caller to have ZT0 state">;
 def err_sme_definition_using_sm_in_non_sme_target : Error<
   "function executed in streaming-SVE mode requires 'sme'">;
 def err_sme_definition_using_za_in_non_sme_target : Error<
   "function using ZA state requires 'sme'">;
+def err_sme_definition_using_zt0_in_non_sme2_target : Error<
+  "function using ZT0 state requires 'sme2'">;
 def err_conflicting_attributes_arm_state : Error<
   "conflicting attributes for state '%0'">;
 def err_unknown_arm_state : Error<
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 1baf895ebaec2c..80b42c8f84a00a 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -951,6 +951,14 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
     OS << " __arm_out(\"za\")";
   if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_InOut)
     OS << " __arm_inout(\"za\")";
+  if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_Preserves)
+    OS << " __arm_preserves(\"zt0\")";
+  if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_In)
+    OS << " __arm_in(\"zt0\")";
+  if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_Out)
+    OS << " __arm_out(\"zt0\")";
+  if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_InOut)
+    OS << " __arm_inout(\"zt0\")";
 
   printFunctionAfter(Info, OS);
 
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index acf6cbad1c7480..0f2c80974b1f35 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1782,6 +1782,16 @@ static void AddAttributesFromFunctionProtoType(ASTContext &Ctx,
     FuncAttrs.addAttribute("aarch64_pstate_za_shared");
     FuncAttrs.addAttribute("aarch64_pstate_za_preserved");
   }
+
+  // ZT0
+  if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_Preserves)
+    FuncAttrs.addAttribute("aarch64_zt0_preserved");
+  if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_In)
+    FuncAttrs.addAttribute("aarch64_zt0_in");
+  if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_Out)
+    FuncAttrs.addAttribute("aarch64_zt0_out");
+  if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_InOut)
+    FuncAttrs.addAttribute("aarch64_zt0_inout");
 }
 
 static void AddAttributesFromAssumes(llvm::AttrBuilder &FuncAttrs,
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 01b042ce5dd134..7c7b825ae3a6b9 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2383,6 +2383,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
   if (auto *Attr = D->getAttr<ArmNewAttr>()) {
     if (Attr->isNewZA())
       B.addAttribute("aarch64_pstate_za_new");
+    if (Attr->isNewZT0())
+      B.addAttribute("aarch64_zt0_new");
   }
 
   // Track whether we need to add the optnone LLVM attribute,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index ace3e386988f00..02d6f1b4d2586b 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7544,6 +7544,28 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
       if (!CallerHasZAState)
         Diag(Loc, diag::err_sme_za_call_no_za_state);
     }
+
+    // If the callee uses AArch64 SME ZT0 state but the caller doesn't define
+    // any, then this is an error.
+    FunctionType::ArmStateValue ArmZT0State =
+        FunctionType::getArmZT0State(ExtInfo.AArch64SMEAttributes);
+    if (ArmZT0State != FunctionType::ARM_None) {
+      bool CallerHasZT0State = false;
+      if (const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext)) {
+        auto *Attr = CallerFD->getAttr<ArmNewAttr>();
+        if (Attr && Attr->isNewZT0())
+          CallerHasZT0State = true;
+        else if (const auto *FPT =
+                     CallerFD->getType()->getAs<FunctionProtoType>())
+          CallerHasZT0State =
+              FunctionType::getArmZT0State(
+                  FPT->getExtProtoInfo().AArch64SMEAttributes) !=
+              FunctionType::ARM_None;
+      }
+
+      if (!CallerHasZT0State)
+        Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
+    }
   }
 
   if (FDecl && FDecl->hasAttr<AllocAlignAttr>()) {
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 4e7049571eeb7a..e2377bb986195e 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12182,12 +12182,15 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
     const auto *Attr = NewFD->getAttr<ArmNewAttr>();
     bool UsesSM = NewFD->hasAttr<ArmLocallyStreamingAttr>();
     bool UsesZA = Attr && Attr->isNewZA();
+    bool UsesZT0 = Attr && Attr->isNewZT0();
     if (const auto *FPT = NewFD->getType()->getAs<FunctionProtoType>()) {
       FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
       UsesSM |=
           EPI.AArch64SMEAttributes & FunctionType::SME_PStateSMEnabledMask;
       UsesZA |= FunctionType::getArmZAState(EPI.AArch64SMEAttributes) !=
                 FunctionType::ARM_None;
+      UsesZT0 |= FunctionType::getArmZT0State(EPI.AArch64SMEAttributes) !=
+                 FunctionType::ARM_None;
     }
 
     if (UsesSM || UsesZA) {
@@ -12202,6 +12205,14 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
                diag::err_sme_definition_using_za_in_non_sme_target);
       }
     }
+    if (UsesZT0) {
+      llvm::StringMap<bool> FeatureMap;
+      Context.getFunctionFeatureMap(FeatureMap, NewFD);
+      if (!FeatureMap.contains("sme2")) {
+        Diag(NewFD->getLocation(),
+             diag::err_sme_definition_using_zt0_in_non_sme2_target);
+      }
+    }
   }
 
   return Redeclaration;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 7e6881049d8d95..946c4503e20b89 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -8988,6 +8988,7 @@ static void handleArmNewAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   }
 
   bool HasZA = false;
+  bool HasZT0 = false;
   for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
     StringRef StateName;
     SourceLocation LiteralLoc;
@@ -8996,6 +8997,8 @@ static void handleArmNewAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
 
     if (StateName == "za")
       HasZA = true;
+    else if (StateName == "zt0")
+      HasZT0 = true;
     else {
       S.Diag(LiteralLoc, diag::err_unknown_arm_state) << StateName;
       AL.setInvalid();
@@ -9014,6 +9017,11 @@ static void handleArmNewAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
     if (HasZA && ZAState != FunctionType::ARM_None &&
         checkArmNewAttrMutualExclusion(S, AL, FPT, ZAState, "za"))
       return;
+    FunctionType::ArmStateValue ZT0State =
+        FunctionType::getArmZT0State(FPT->getAArch64SMEAttributes());
+    if (HasZT0 && ZT0State != FunctionType::ARM_None &&
+        checkArmNewAttrMutualExclusion(S, AL, FPT, ZT0State, "zt0"))
+      return;
   }
 
   D->dropAttr<ArmNewAttr>();
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 78702b41ab8200..26b5d7da59b0a6 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -7899,6 +7899,9 @@ static bool handleArmStateAttribute(Sema &S,
     if (StateName == "za") {
       Shift = FunctionType::SME_ZAShift;
       ExistingState = FunctionType::getArmZAState(EPI.AArch64SMEAttributes);
+    } else if (StateName == "zt0") {
+      Shift = FunctionType::SME_ZT0Shift;
+      ExistingState = FunctionType::getArmZT0State(EPI.AArch64SMEAttributes);
     } else {
       S.Diag(LiteralLoc, diag::err_unknown_arm_state) << StateName;
       Attr.setInvalid();
diff --git a/clang/test/CodeGen/aarch64-sme2-intrinsics/aarch64-sme2-attrs.cpp b/clang/test/CodeGen/aarch64-sme2-intrinsics/aarch64-sme2-attrs.cpp
new file mode 100644
index 00000000000000..f0a5ea265920ce
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-sme2-intrinsics/aarch64-sme2-attrs.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 \
+// RUN:   -S -disable-O0-optnone -Werror -emit-llvm -o - %s \
+// RUN: | opt -S -passes=mem2reg \
+// RUN: | opt -S -passes=inline \
+// RUN: | FileCheck %s
+
+// Test the attributes for ZT0 and their mappings to LLVM IR.
+
+extern "C" {
+
+// CHECK-LABEL: @in_zt0()
+// CHECK-SAME: #[[ZT0_IN:[0-9]+]]
+void in_zt0() __arm_in("zt0") { }
+
+// CHECK-LABEL: @out_zt0()
+// CHECK-SAME: #[[ZT0_OUT:[0-9]+]]
+void out_zt0() __arm_out("zt0") { }
+
+// CHECK-LABEL: @inout_zt0()
+// CHECK-SAME: #[[ZT0_INOUT:[0-9]+]]
+void inout_zt0() __arm_inout("zt0") { }
+
+// CHECK-LABEL: @preserves_zt0()
+// CHECK-SAME: #[[ZT0_PRESERVED:[0-9]+]]
+void preserves_zt0() __arm_preserves("zt0") { }
+
+// CHECK-LABEL: @new_zt0()
+// CHECK-SAME: #[[ZT0_NEW:[0-9]+]]
+__arm_new("zt0") void new_zt0() { }
+
+// CHECK-LABEL: @in_za_zt0()
+// CHECK-SAME: #[[ZA_ZT0_IN:[0-9]+]]
+void in_za_zt0() __arm_in("za", "zt0") { }
+
+// CHECK-LABEL: @out_za_zt0()
+// CHECK-SAME: #[[ZA_ZT0_OUT:[0-9]+]]
+void out_za_zt0() __arm_out("za", "zt0") { }
+
+// CHECK-LABEL: @inout_za_zt0()
+// CHECK-SAME: #[[ZA_ZT0_INOUT:[0-9]+]]
+void inout_za_zt0() __arm_inout("za", "zt0") { }
+
+// CHECK-LABEL: @preserves_za_zt0()
+// CHECK-SAME: #[[ZA_ZT0_PRESERVED:[0-9]+]]
+void preserves_za_zt0() __arm_preserves("za", "zt0") { }
+
+// CHECK-LABEL: @new_za_zt0()
+// CHECK-SAME: #[[ZA_ZT0_NEW:[0-9]+]]
+__arm_new("za", "zt0") void new_za_zt0() { }
+
+}
+
+// CHECK: attributes #[[ZT0_IN]] = {{{.*}} "aarch64_zt0_in" {{.*}}}
+// CHECK: attributes #[[ZT0_OUT]] = {{{.*}} "aarch64_zt0_out" {{.*}}}
+// CHECK: attributes #[[ZT0_INOUT]] = {{{.*}} "aarch64_zt0_inout" {{.*}}}
+// CHECK: attributes #[[ZT0_PRESERVED]] = {{{.*}} "aarch64_zt0_preserved" {{.*}}}
+// CHECK: attributes #[[ZT0_NEW]] = {{{.*}} "aarch64_zt0_new" {{.*}}}
diff --git a/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp b/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
index 0a54a94f408b79..ec6bb6f5035784 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
+++ b/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
@@ -8,6 +8,8 @@ void shared_za_def() __arm_inout("za") { } // expected-error {{function using ZA
 __arm_new("za") void new_za_def() { } // expected-error {{function using ZA state requires 'sme'}}
 __arm_locally_streaming void locally_streaming_def() { } // expected-error {{function executed in streaming-SVE mode requires 'sme'}}
 void streaming_shared_za_def() __arm_streaming __arm_inout("za") { } // expected-error {{function executed in streaming-SVE mode requires 'sme'}}
+void inout_za_def() __arm_inout("za") { } // expected-error {{function using ZA state requires 'sme'}}
+void inout_zt0_def() __arm_inout("zt0") { } // expected-error {{function using ZT0 state requires 'sme2'}}
 
 // It should work fine when we explicitly add the target("sme") attribute.
 __attribute__((target("sme"))) void streaming_compatible_def_sme_attr() __arm_streaming_compatible {} // OK
diff --git a/clang/test/Sema/aarch64-sme-func-attrs.c b/clang/test/Sema/aarch64-sme-func-attrs.c
index b986b0b3de2e14..b8a1d91a4b7e09 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs.c
+++ b/clang/test/Sema/aarch64-sme-func-attrs.c
@@ -353,6 +353,11 @@ void invalid_arm_in_unknown_state(void) __arm_in("unknownstate");
 
 void valid_state_attrs_in_in1(void) __arm_in("za");
 void valid_state_attrs_in_in2(void) __arm_in("za", "za");
+void valid_state_attrs_in_in3(void) __arm_in("zt0");
+void valid_state_attrs_in_in4(void) __arm_in("zt0", "zt0");
+void valid_state_attrs_in_in5(void) __arm_in("za", "zt0");
+__arm_new("za") void valid_state_attrs_in_in6(void) __arm_in("zt0");
+__arm_new("zt0") void valid_state_attrs_in_in7(void) __arm_in("za");
 
 // expected-cpp-error at +2 {{missing state for '__arm_in'}}
 // expected-error at +1 {{missing state for '__arm_in'}}
@@ -400,3 +405,43 @@ void conflicting_state_attrs_preserves_out(void) __arm_preserves("za") __arm_out
 // expected-cpp-error at +2 {{conflicting attributes for state 'za'}}
 // expected-error at +1 {{conflicting attributes for state 'za'}}
 void conflicting_state_attrs_preserves_inout(void) __arm_preserves("za") __arm_inout("za");
+
+// expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
+// expected-error at +1 {{conflicting attributes for state 'zt0'}}
+void conflicting_state_attrs_in_out(void) __arm_in("zt0") __arm_out("zt0");
+// expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
+// expected-error at +1 {{conflicting attributes for state 'zt0'}}
+void conflicting_state_attrs_in_inout(void) __arm_in("zt0") __arm_inout("zt0");
+// expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
+// expected-error at +1 {{conflicting attributes for state 'zt0'}}
+void conflicting_state_attrs_in_preserves(void) __arm_in("zt0") __arm_preserves("zt0");
+
+// expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
+// expected-error at +1 {{conflicting attributes for state 'zt0'}}
+void conflicting_state_attrs_out_in(void) __arm_out("zt0") __arm_in("zt0");
+// expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
+// expected-error at +1 {{conflicting attributes for state 'zt0'}}
+void conflicting_state_attrs_out_inout(void) __arm_out("zt0") __arm_inout("zt0");
+// expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
+// expected-error at +1 {{conflicting attributes for state 'zt0'}}
+void conflicting_state_attrs_out_preserves(void) __arm_out("zt0") __arm_preserves("zt0");
+
+// expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
+// expected-error at +1 {{conflicting attributes for state 'zt0'}}
+void conflicting_state_attrs_inout_in(void) __arm_inout("zt0") __arm_in("zt0");
+// expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
+// expected-error at +1 {{conflicting attributes for state 'zt0'}}
+void conflicting_state_attrs_inout_out(void) __arm_inout("zt0") __arm_out("zt0");
+// expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
+// expected-error at +1 {{conflicting attributes for state 'zt0'}}
+void conflicting_state_attrs_inout_preserves(void) __arm_inout("zt0") __arm_preserves("zt0");
+
+// expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
+// expected-error at +1 {{conflicting attributes for state 'zt0'}}
+void conflicting_state_attrs_preserves_in(void) __arm_preserves("zt0") __arm_in("zt0");
+// expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
+// expected-error at +1 {{conflicting attributes for state 'zt0'}}
+void conflicting_state_attrs_preserves_out(void) __arm_preserves("zt0") __arm_out("zt0");
+// expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
+// expected-error at +1 {{conflicting attributes for state 'zt0'}}
+void conflicting_state_attrs_preserves_inout(void) __arm_preserves("zt0") __arm_inout("zt0");

>From 704db68be3e4c11d695aed83d38120145480529e Mon Sep 17 00:00:00 2001
From: Sander de Smalen <sander.desmalen at arm.com>
Date: Mon, 15 Jan 2024 12:57:55 +0000
Subject: [PATCH 2/2] Fix up failing aarch64-sme-func-attrs.c [to sqsuash]

Due to duplication of names, this test was failing.
---
 clang/test/Sema/aarch64-sme-func-attrs.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/clang/test/Sema/aarch64-sme-func-attrs.c b/clang/test/Sema/aarch64-sme-func-attrs.c
index b8a1d91a4b7e09..97409ae7d6040c 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs.c
+++ b/clang/test/Sema/aarch64-sme-func-attrs.c
@@ -408,40 +408,40 @@ void conflicting_state_attrs_preserves_inout(void) __arm_preserves("za") __arm_i
 
 // expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
 // expected-error at +1 {{conflicting attributes for state 'zt0'}}
-void conflicting_state_attrs_in_out(void) __arm_in("zt0") __arm_out("zt0");
+void conflicting_state_attrs_in_out_zt0(void) __arm_in("zt0") __arm_out("zt0");
 // expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
 // expected-error at +1 {{conflicting attributes for state 'zt0'}}
-void conflicting_state_attrs_in_inout(void) __arm_in("zt0") __arm_inout("zt0");
+void conflicting_state_attrs_in_inout_zt0(void) __arm_in("zt0") __arm_inout("zt0");
 // expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
 // expected-error at +1 {{conflicting attributes for state 'zt0'}}
-void conflicting_state_attrs_in_preserves(void) __arm_in("zt0") __arm_preserves("zt0");
+void conflicting_state_attrs_in_preserves_zt0(void) __arm_in("zt0") __arm_preserves("zt0");
 
 // expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
 // expected-error at +1 {{conflicting attributes for state 'zt0'}}
-void conflicting_state_attrs_out_in(void) __arm_out("zt0") __arm_in("zt0");
+void conflicting_state_attrs_out_in_zt0(void) __arm_out("zt0") __arm_in("zt0");
 // expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
 // expected-error at +1 {{conflicting attributes for state 'zt0'}}
-void conflicting_state_attrs_out_inout(void) __arm_out("zt0") __arm_inout("zt0");
+void conflicting_state_attrs_out_inout_zt0(void) __arm_out("zt0") __arm_inout("zt0");
 // expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
 // expected-error at +1 {{conflicting attributes for state 'zt0'}}
-void conflicting_state_attrs_out_preserves(void) __arm_out("zt0") __arm_preserves("zt0");
+void conflicting_state_attrs_out_preserves_zt0(void) __arm_out("zt0") __arm_preserves("zt0");
 
 // expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
 // expected-error at +1 {{conflicting attributes for state 'zt0'}}
-void conflicting_state_attrs_inout_in(void) __arm_inout("zt0") __arm_in("zt0");
+void conflicting_state_attrs_inout_in_zt0(void) __arm_inout("zt0") __arm_in("zt0");
 // expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
 // expected-error at +1 {{conflicting attributes for state 'zt0'}}
-void conflicting_state_attrs_inout_out(void) __arm_inout("zt0") __arm_out("zt0");
+void conflicting_state_attrs_inout_out_zt0(void) __arm_inout("zt0") __arm_out("zt0");
 // expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
 // expected-error at +1 {{conflicting attributes for state 'zt0'}}
-void conflicting_state_attrs_inout_preserves(void) __arm_inout("zt0") __arm_preserves("zt0");
+void conflicting_state_attrs_inout_preserves_zt0(void) __arm_inout("zt0") __arm_preserves("zt0");
 
 // expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
 // expected-error at +1 {{conflicting attributes for state 'zt0'}}
-void conflicting_state_attrs_preserves_in(void) __arm_preserves("zt0") __arm_in("zt0");
+void conflicting_state_attrs_preserves_in_zt0(void) __arm_preserves("zt0") __arm_in("zt0");
 // expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
 // expected-error at +1 {{conflicting attributes for state 'zt0'}}
-void conflicting_state_attrs_preserves_out(void) __arm_preserves("zt0") __arm_out("zt0");
+void conflicting_state_attrs_preserves_out_zt0(void) __arm_preserves("zt0") __arm_out("zt0");
 // expected-cpp-error at +2 {{conflicting attributes for state 'zt0'}}
 // expected-error at +1 {{conflicting attributes for state 'zt0'}}
-void conflicting_state_attrs_preserves_inout(void) __arm_preserves("zt0") __arm_inout("zt0");
+void conflicting_state_attrs_preserves_inout_zt0(void) __arm_preserves("zt0") __arm_inout("zt0");



More information about the cfe-commits mailing list