[llvm] ecb7b9c - [Clang][AArch64] Diagnostics for SME attributes when target doesn't have 'sme'

Sander de Smalen via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 9 05:31:34 PDT 2023


Author: Sander de Smalen
Date: 2023-08-09T12:31:02Z
New Revision: ecb7b9c5c589b693e8a7351461db5b520be0bc90

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

LOG: [Clang][AArch64] Diagnostics for SME attributes when target doesn't have 'sme'

This patch adds error diagnostics to Clang when code uses the AArch64 SME
attributes without specifying 'sme' as available target attribute.

* Function definitions marked as '__arm_streaming', '__arm_locally_streaming',
  '__arm_shared_za' or '__arm_new_za' will by definition use or require SME
  instructions.
* Calls from non-streaming functions to streaming-functions require
  the compiler to enable/disable streaming-SVE mode around the call-site.

In some cases we can accept the SME attributes without having 'sme' enabled:
* Function declaration can have the SME attributes.
* Definitions can be __arm_streaming_compatible since the generated
  code should execute on processing elements without SME.

Reviewed By: paulwalker-arm

Differential Revision: https://reviews.llvm.org/D157269

Added: 
    clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
    llvm/test/CodeGen/AArch64/sme-call-streaming-compatible-to-normal-fn-wihout-sme-attr.ll

Modified: 
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaChecking.cpp
    clang/lib/Sema/SemaDecl.cpp
    llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
    llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
    llvm/lib/Target/AArch64/SMEInstrFormats.td
    llvm/test/MC/AArch64/SME/directives-negative.s
    llvm/test/MC/AArch64/SME/smstart.s
    llvm/test/MC/AArch64/SME/smstop.s
    llvm/test/MC/AArch64/SME/system-regs.s

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d242e40be32b6c..9017d5ad3711c9 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3627,6 +3627,12 @@ def err_attribute_vecreturn_only_pod_record : Error<
   "the vecreturn attribute can only be used on a POD (plain old data) class or structure (i.e. no virtual functions)">;
 def err_sme_attr_mismatch : Error<
   "function declared %0 was previously declared %1, which has 
diff erent SME function attributes">;
+def err_sme_call_in_non_sme_target : Error<
+  "call to a streaming function requires 'sme'">;
+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_cconv_change : Error<
   "function declared '%0' here was previously declared "
   "%select{'%2'|without calling convention}1">;

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0b377d40747429..e2bf759307e99b 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -6715,8 +6715,8 @@ void Sema::CheckArgAlignment(SourceLocation Loc, NamedDecl *FDecl,
 }
 
 /// Handles the checks for format strings, non-POD arguments to vararg
-/// functions, NULL arguments passed to non-NULL parameters, and diagnose_if
-/// attributes.
+/// functions, NULL arguments passed to non-NULL parameters, diagnose_if
+/// attributes and AArch64 SME attributes.
 void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
                      const Expr *ThisArg, ArrayRef<const Expr *> Args,
                      bool IsMemberFunction, SourceLocation Loc,
@@ -6797,6 +6797,20 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
                           ArgTy, ParamTy);
       }
     }
+
+    // If the callee has an AArch64 SME attribute to indicate that it is an
+    // __arm_streaming function, then the caller requires SME to be available.
+    FunctionProtoType::ExtProtoInfo ExtInfo = Proto->getExtProtoInfo();
+    if (ExtInfo.AArch64SMEAttributes & FunctionType::SME_PStateSMEnabledMask) {
+      if (auto *CallerFD = dyn_cast<FunctionDecl>(CurContext)) {
+        llvm::StringMap<bool> CallerFeatureMap;
+        Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
+        if (!CallerFeatureMap.contains("sme"))
+          Diag(Loc, diag::err_sme_call_in_non_sme_target);
+      } else if (!Context.getTargetInfo().hasFeature("sme")) {
+        Diag(Loc, diag::err_sme_call_in_non_sme_target);
+      }
+    }
   }
 
   if (FDecl && FDecl->hasAttr<AllocAlignAttr>()) {

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d250b4382753bb..1d2a14e87323ca 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12140,6 +12140,33 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
     if (!Redeclaration && LangOpts.CUDA)
       checkCUDATargetOverload(NewFD, Previous);
   }
+
+  // Check if the function definition uses any AArch64 SME features without
+  // having the '+sme' feature enabled.
+  if (DeclIsDefn) {
+    bool UsesSM = NewFD->hasAttr<ArmLocallyStreamingAttr>();
+    bool UsesZA = NewFD->hasAttr<ArmNewZAAttr>();
+    if (const auto *FPT = NewFD->getType()->getAs<FunctionProtoType>()) {
+      FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
+      UsesSM |=
+          EPI.AArch64SMEAttributes & FunctionType::SME_PStateSMEnabledMask;
+      UsesZA |= EPI.AArch64SMEAttributes & FunctionType::SME_PStateZASharedMask;
+    }
+
+    if (UsesSM || UsesZA) {
+      llvm::StringMap<bool> FeatureMap;
+      Context.getFunctionFeatureMap(FeatureMap, NewFD);
+      if (!FeatureMap.contains("sme")) {
+        if (UsesSM)
+          Diag(NewFD->getLocation(),
+               diag::err_sme_definition_using_sm_in_non_sme_target);
+        else
+          Diag(NewFD->getLocation(),
+               diag::err_sme_definition_using_za_in_non_sme_target);
+      }
+    }
+  }
+
   return Redeclaration;
 }
 

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
new file mode 100644
index 00000000000000..b59d67f7f57b88
--- /dev/null
+++ b/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify %s
+
+// This test is testing the diagnostics that Clang emits when compiling without '+sme'.
+
+void streaming_compatible_def() __arm_streaming_compatible {} // OK
+void streaming_def() __arm_streaming { } // expected-error {{function executed in streaming-SVE mode requires 'sme'}}
+void shared_za_def() __arm_shared_za { } // expected-error {{function using ZA state requires 'sme'}}
+__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_shared_za { } // expected-error {{function executed in streaming-SVE mode requires 'sme'}}
+
+// 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
+__attribute__((target("sme"))) void streaming_def_sme_attr() __arm_streaming { } // OK
+__attribute__((target("sme"))) void shared_za_def_sme_attr() __arm_shared_za { } // OK
+__arm_new_za __attribute__((target("sme"))) void new_za_def_sme_attr() {} // OK
+__arm_locally_streaming __attribute__((target("sme"))) void locally_streaming_def_sme_attr() {} // OK
+
+// Test that it also works with the target("sme2") attribute.
+__attribute__((target("sme2"))) void streaming_def_sme2_attr() __arm_streaming { } // OK
+
+// No code is generated for declarations, so it should be fine to declare using the attribute.
+void streaming_compatible_decl() __arm_streaming_compatible; // OK
+void streaming_decl() __arm_streaming; // OK
+void shared_za_decl() __arm_shared_za; // OK
+
+void non_streaming_decl();
+void non_streaming_def(void (*streaming_fn_ptr)(void) __arm_streaming,
+                       void (*streaming_compatible_fn_ptr)(void) __arm_streaming_compatible) {
+  streaming_compatible_decl(); // OK
+  streaming_compatible_fn_ptr(); // OK
+  streaming_decl(); // expected-error {{call to a streaming function requires 'sme'}}
+  streaming_fn_ptr(); // expected-error {{call to a streaming function requires 'sme'}}
+}
+
+void streaming_compatible_def2(void (*streaming_fn_ptr)(void) __arm_streaming,
+                               void (*streaming_compatible_fn_ptr)(void) __arm_streaming_compatible)
+                                __arm_streaming_compatible {
+  non_streaming_decl(); // OK
+  streaming_compatible_decl(); // OK
+  streaming_compatible_fn_ptr(); // OK
+  streaming_decl(); // expected-error {{call to a streaming function requires 'sme'}}
+  streaming_fn_ptr(); // expected-error {{call to a streaming function requires 'sme'}}
+}
+
+// Also test when call-site is not a function.
+int streaming_decl_ret_int() __arm_streaming;
+int x = streaming_decl_ret_int(); // expected-error {{call to a streaming function requires 'sme'}}

diff  --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
index cabfe9def7c293..352f34cab132ad 100644
--- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
@@ -134,52 +134,6 @@ defm ZERO_M : sme_zero<"zero">;
 // Mode selection and state access instructions
 //===----------------------------------------------------------------------===//
 
-// SME defines three pstate fields to set or clear PSTATE.SM, PSTATE.ZA, or
-// both fields:
-//
-//   MSR SVCRSM, #<imm1>
-//   MSR SVCRZA, #<imm1>
-//   MSR SVCRSMZA, #<imm1>
-//
-// It's tricky to using the existing pstate operand defined in
-// AArch64SystemOperands.td since it only encodes 5 bits including op1;op2,
-// when these fields are also encoded in CRm[3:1].
-def MSRpstatesvcrImm1
-  : PstateWriteSimple<(ins svcr_op:$pstatefield, timm0_1:$imm), "msr",
-                      "\t$pstatefield, $imm">,
-    Sched<[WriteSys]> {
-  bits<3> pstatefield;
-  bit imm;
-  let Inst{18-16} = 0b011; // op1
-  let Inst{11-9} = pstatefield;
-  let Inst{8} = imm;
-  let Inst{7-5} = 0b011; // op2
-}
-
-def : InstAlias<"smstart",    (MSRpstatesvcrImm1 0b011, 0b1)>;
-def : InstAlias<"smstart sm", (MSRpstatesvcrImm1 0b001, 0b1)>;
-def : InstAlias<"smstart za", (MSRpstatesvcrImm1 0b010, 0b1)>;
-
-def : InstAlias<"smstop",     (MSRpstatesvcrImm1 0b011, 0b0)>;
-def : InstAlias<"smstop sm",  (MSRpstatesvcrImm1 0b001, 0b0)>;
-def : InstAlias<"smstop za",  (MSRpstatesvcrImm1 0b010, 0b0)>;
-
-
-// Pseudo to match to smstart/smstop. This expands:
-//
-//  pseudonode (pstate_za|pstate_sm), before_call, expected_value
-//
-// Into:
-//
-//   if (before_call != expected_value)
-//     node (pstate_za|pstate_sm)
-//
-// where node can be either 'smstart' or 'smstop'.
-def MSRpstatePseudo :
-  Pseudo<(outs),
-           (ins svcr_op:$pstatefield, timm0_1:$imm, GPR64:$rtpstate, timm0_1:$expected_pstate, variable_ops), []>,
-    Sched<[WriteSys]>;
-
 // Pseudo to conditionally restore ZA state. This expands:
 //
 //   pseudonode tpidr2_el0, tpidr2obj, restore_routine
@@ -226,12 +180,6 @@ def : Pat<(AArch64_smstart (i32 svcr_op:$pstate), (i64 0), (i64 1)),  // before
 def : Pat<(AArch64_smstop (i32 svcr_op:$pstate), (i64 0), (i64 1)),   // after call
           (MSRpstatesvcrImm1 svcr_op:$pstate, 0b0)>;
 
-// The generic case which gets expanded to a pseudo node.
-def : Pat<(AArch64_smstart (i32 svcr_op:$pstate), (i64 GPR64:$rtpstate), (i64 timm0_1:$expected_pstate)),
-          (MSRpstatePseudo svcr_op:$pstate, 0b1, GPR64:$rtpstate, timm0_1:$expected_pstate)>;
-def : Pat<(AArch64_smstop (i32 svcr_op:$pstate), (i64 GPR64:$rtpstate), (i64 timm0_1:$expected_pstate)),
-          (MSRpstatePseudo svcr_op:$pstate, 0b0, GPR64:$rtpstate, timm0_1:$expected_pstate)>;
-
 // Read and write TPIDR2_EL0
 def : Pat<(int_aarch64_sme_set_tpidr2 i64:$val),
           (MSR 0xde85, GPR64:$val)>;
@@ -243,6 +191,31 @@ def : Pat<(i64 (AArch64ObscureCopy (i64 GPR64:$idx))),
           (OBSCURE_COPY GPR64:$idx)>;
 } // End let Predicates = [HasSME]
 
+// Pseudo to match to smstart/smstop. This expands:
+//
+//  pseudonode (pstate_za|pstate_sm), before_call, expected_value
+//
+// Into:
+//
+//   if (before_call != expected_value)
+//     node (pstate_za|pstate_sm)
+//
+// where node can be either 'smstart' or 'smstop'.
+//
+// This pseudo and corresponding patterns don't need to be predicated by SME,
+// because when they're emitted for streaming-compatible functions and run
+// in a non-SME context the generated code-paths will never execute any
+// SME instructions.
+def MSRpstatePseudo :
+  Pseudo<(outs),
+           (ins svcr_op:$pstatefield, timm0_1:$imm, GPR64:$rtpstate, timm0_1:$expected_pstate, variable_ops), []>,
+    Sched<[WriteSys]>;
+
+def : Pat<(AArch64_smstart (i32 svcr_op:$pstate), (i64 GPR64:$rtpstate), (i64 timm0_1:$expected_pstate)),
+          (MSRpstatePseudo svcr_op:$pstate, 0b1, GPR64:$rtpstate, timm0_1:$expected_pstate)>;
+def : Pat<(AArch64_smstop (i32 svcr_op:$pstate), (i64 GPR64:$rtpstate), (i64 timm0_1:$expected_pstate)),
+          (MSRpstatePseudo svcr_op:$pstate, 0b0, GPR64:$rtpstate, timm0_1:$expected_pstate)>;
+
 //===----------------------------------------------------------------------===//
 // SME2 Instructions
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
index 9d03e65c979961..6f7fccdf84fed9 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -442,8 +442,6 @@ AArch64TargetMachine::getSubtargetImpl(const Function &F) const {
 
   assert((!StreamingSVEMode || I->hasSME()) &&
          "Expected SME to be available");
-  assert((!StreamingCompatibleSVEMode || I->hasSVEorSME()) &&
-         "Expected SVE or SME to be available");
 
   return I.get();
 }

diff  --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td
index 6e3aadd5dd8cc7..b135fec03a8c61 100644
--- a/llvm/lib/Target/AArch64/SMEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td
@@ -190,6 +190,42 @@ class SME_ZA_Tile_TwoPred_TwoVec_Pat<string name, SDPatternOperator intrinsic, O
     : Pat<(intrinsic imm_ty:$tile, (pg_ty PPR3bAny:$Pn), (pg_ty PPR3bAny:$Pm), vt:$Zn, vt:$Zm),
           (!cast<Instruction>(name # _PSEUDO) $tile, $Pn, $Pm, $Zn, $Zm)>;
 
+
+//===----------------------------------------------------------------------===//
+// SME smstart/smstop
+//===----------------------------------------------------------------------===//
+
+// SME defines three pstate fields to set or clear PSTATE.SM, PSTATE.ZA, or
+// both fields:
+//
+//   MSR SVCRSM, #<imm1>
+//   MSR SVCRZA, #<imm1>
+//   MSR SVCRSMZA, #<imm1>
+//
+// It's tricky to using the existing pstate operand defined in
+// AArch64SystemOperands.td since it only encodes 5 bits including op1;op2,
+// when these fields are also encoded in CRm[3:1].
+def MSRpstatesvcrImm1
+  : PstateWriteSimple<(ins svcr_op:$pstatefield, timm0_1:$imm), "msr",
+                      "\t$pstatefield, $imm">,
+    Sched<[WriteSys]> {
+  bits<3> pstatefield;
+  bit imm;
+  let Inst{18-16} = 0b011; // op1
+  let Inst{11-9} = pstatefield;
+  let Inst{8} = imm;
+  let Inst{7-5} = 0b011; // op2
+}
+
+def : InstAlias<"smstart",    (MSRpstatesvcrImm1 0b011, 0b1)>;
+def : InstAlias<"smstart sm", (MSRpstatesvcrImm1 0b001, 0b1)>;
+def : InstAlias<"smstart za", (MSRpstatesvcrImm1 0b010, 0b1)>;
+
+def : InstAlias<"smstop",     (MSRpstatesvcrImm1 0b011, 0b0)>;
+def : InstAlias<"smstop sm",  (MSRpstatesvcrImm1 0b001, 0b0)>;
+def : InstAlias<"smstop za",  (MSRpstatesvcrImm1 0b010, 0b0)>;
+
+
 //===----------------------------------------------------------------------===//
 // SME Outer Products
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/test/CodeGen/AArch64/sme-call-streaming-compatible-to-normal-fn-wihout-sme-attr.ll b/llvm/test/CodeGen/AArch64/sme-call-streaming-compatible-to-normal-fn-wihout-sme-attr.ll
new file mode 100644
index 00000000000000..cffbadc5355239
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/sme-call-streaming-compatible-to-normal-fn-wihout-sme-attr.ll
@@ -0,0 +1,41 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc < %s | FileCheck %s
+
+; Verify that the following code can be compiled without +sme, because if the
+; call is not entered in streaming-SVE mode at runtime, the codepath leading
+; to the smstop/smstart pair will not be executed either.
+
+target triple = "aarch64"
+
+define void @streaming_compatible() #0 {
+; CHECK-LABEL: streaming_compatible:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    stp d15, d14, [sp, #-80]! // 16-byte Folded Spill
+; CHECK-NEXT:    stp d13, d12, [sp, #16] // 16-byte Folded Spill
+; CHECK-NEXT:    stp d11, d10, [sp, #32] // 16-byte Folded Spill
+; CHECK-NEXT:    stp d9, d8, [sp, #48] // 16-byte Folded Spill
+; CHECK-NEXT:    stp x30, x19, [sp, #64] // 16-byte Folded Spill
+; CHECK-NEXT:    bl __arm_sme_state
+; CHECK-NEXT:    and x19, x0, #0x1
+; CHECK-NEXT:    tbz x19, #0, .LBB0_2
+; CHECK-NEXT:  // %bb.1:
+; CHECK-NEXT:    smstop sm
+; CHECK-NEXT:  .LBB0_2:
+; CHECK-NEXT:    bl non_streaming
+; CHECK-NEXT:    tbz x19, #0, .LBB0_4
+; CHECK-NEXT:  // %bb.3:
+; CHECK-NEXT:    smstart sm
+; CHECK-NEXT:  .LBB0_4:
+; CHECK-NEXT:    ldp x30, x19, [sp, #64] // 16-byte Folded Reload
+; CHECK-NEXT:    ldp d9, d8, [sp, #48] // 16-byte Folded Reload
+; CHECK-NEXT:    ldp d11, d10, [sp, #32] // 16-byte Folded Reload
+; CHECK-NEXT:    ldp d13, d12, [sp, #16] // 16-byte Folded Reload
+; CHECK-NEXT:    ldp d15, d14, [sp], #80 // 16-byte Folded Reload
+; CHECK-NEXT:    ret
+  call void @non_streaming()
+  ret void
+}
+
+declare void @non_streaming()
+
+attributes #0 = { nounwind "aarch64_pstate_sm_compatible" }

diff  --git a/llvm/test/MC/AArch64/SME/directives-negative.s b/llvm/test/MC/AArch64/SME/directives-negative.s
index 3df90b3016869e..123c3a383d71ef 100644
--- a/llvm/test/MC/AArch64/SME/directives-negative.s
+++ b/llvm/test/MC/AArch64/SME/directives-negative.s
@@ -2,9 +2,9 @@
 
 .arch_extension sme
 .arch_extension nosme
-smstart
+zero {za}
 // CHECK: error: instruction requires: sme
-// CHECK-NEXT: smstart
+// CHECK-NEXT: zero {za}
 
 .arch_extension sme-f64f64
 .arch_extension nosme-f64f64
@@ -20,9 +20,9 @@ addha za0.d, p0/m, p0/m, z0.d
 
 .arch armv9-a+sme
 .arch armv9-a+nosme
-smstart
+zero {za}
 // CHECK: error: instruction requires: sme
-// CHECK-NEXT: smstart
+// CHECK-NEXT: zero {za}
 
 .arch armv9-a+sme-f64f64
 .arch armv9-a+nosme-f64f64

diff  --git a/llvm/test/MC/AArch64/SME/smstart.s b/llvm/test/MC/AArch64/SME/smstart.s
index 1628a279bb3535..07a696d28df8c8 100644
--- a/llvm/test/MC/AArch64/SME/smstart.s
+++ b/llvm/test/MC/AArch64/SME/smstart.s
@@ -1,38 +1,28 @@
 // RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %s \
 // RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
-// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
-// RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
 // RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme < %s \
 // RUN:        | llvm-objdump -d --mattr=+sme - | FileCheck %s --check-prefix=CHECK-INST
 // RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme < %s \
-// RUN:   | llvm-objdump -d --mattr=-sme - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN:        | llvm-objdump -d --mattr=-sme - | FileCheck %s --check-prefix=CHECK-INST
 
 smstart
 // CHECK-INST: smstart
 // CHECK-ENCODING: [0x7f,0x47,0x03,0xd5]
-// CHECK-ERROR: instruction requires: sme
-// CHECK-UNKNOWN: d503477f   msr   S0_3_C4_C7_3, xzr
 
 smstart sm
 // CHECK-INST: smstart sm
 // CHECK-ENCODING: [0x7f,0x43,0x03,0xd5]
-// CHECK-ERROR: instruction requires: sme
-// CHECK-UNKNOWN: d503437f   msr   S0_3_C4_C3_3, xzr
 
 smstart za
 // CHECK-INST: smstart za
 // CHECK-ENCODING: [0x7f,0x45,0x03,0xd5]
-// CHECK-ERROR: instruction requires: sme
-// CHECK-UNKNOWN: d503457f   msr   S0_3_C4_C5_3, xzr
 
 smstart SM
 // CHECK-INST: smstart sm
 // CHECK-ENCODING: [0x7f,0x43,0x03,0xd5]
-// CHECK-ERROR: instruction requires: sme
-// CHECK-UNKNOWN: d503437f   msr   S0_3_C4_C3_3, xzr
 
 smstart ZA
 // CHECK-INST: smstart za
 // CHECK-ENCODING: [0x7f,0x45,0x03,0xd5]
-// CHECK-ERROR: instruction requires: sme
-// CHECK-UNKNOWN: d503457f   msr   S0_3_C4_C5_3, xzr

diff  --git a/llvm/test/MC/AArch64/SME/smstop.s b/llvm/test/MC/AArch64/SME/smstop.s
index b7c21d939e9a9d..df9d1118d96fff 100644
--- a/llvm/test/MC/AArch64/SME/smstop.s
+++ b/llvm/test/MC/AArch64/SME/smstop.s
@@ -1,38 +1,28 @@
 // RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %s \
 // RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
-// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
-// RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
 // RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme < %s \
 // RUN:        | llvm-objdump -d --mattr=+sme - | FileCheck %s --check-prefix=CHECK-INST
 // RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme < %s \
-// RUN:   | llvm-objdump -d --mattr=-sme - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN:        | llvm-objdump -d --mattr=-sme - | FileCheck %s --check-prefix=CHECK-INST
 
 smstop
 // CHECK-INST: smstop
 // CHECK-ENCODING: [0x7f,0x46,0x03,0xd5]
-// CHECK-ERROR: instruction requires: sme
-// CHECK-UNKNOWN: d503467f   msr   S0_3_C4_C6_3, xzr
 
 smstop sm
 // CHECK-INST: smstop sm
 // CHECK-ENCODING: [0x7f,0x42,0x03,0xd5]
-// CHECK-ERROR: instruction requires: sme
-// CHECK-UNKNOWN: d503427f   msr   S0_3_C4_C2_3, xzr
 
 smstop za
 // CHECK-INST: smstop za
 // CHECK-ENCODING: [0x7f,0x44,0x03,0xd5]
-// CHECK-ERROR: instruction requires: sme
-// CHECK-UNKNOWN: d503447f   msr   S0_3_C4_C4_3, xzr
 
 smstop SM
 // CHECK-INST: smstop sm
 // CHECK-ENCODING: [0x7f,0x42,0x03,0xd5]
-// CHECK-ERROR: instruction requires: sme
-// CHECK-UNKNOWN: d503427f   msr   S0_3_C4_C2_3, xzr
 
 smstop ZA
 // CHECK-INST: smstop za
 // CHECK-ENCODING: [0x7f,0x44,0x03,0xd5]
-// CHECK-ERROR: instruction requires: sme
-// CHECK-UNKNOWN: d503447f   msr   S0_3_C4_C4_3, xzr

diff  --git a/llvm/test/MC/AArch64/SME/system-regs.s b/llvm/test/MC/AArch64/SME/system-regs.s
index 48033d026c44bd..093b64a70fb931 100644
--- a/llvm/test/MC/AArch64/SME/system-regs.s
+++ b/llvm/test/MC/AArch64/SME/system-regs.s
@@ -119,37 +119,37 @@ msr SVCRSM, #0
 // CHECK-INST: smstop sm
 // CHECK-ENCODING: [0x7f,0x42,0x03,0xd5]
 // CHECK-ERROR: expected writable system register or pstate
-// CHECK-UNKNOWN: d503427f   msr   S0_3_C4_C2_3, xzr
+// CHECK-UNKNOWN: d503427f   smstop sm
 
 msr SVCRSM, #1
 // CHECK-INST: smstart
 // CHECK-ENCODING: [0x7f,0x43,0x03,0xd5]
 // CHECK-ERROR: expected writable system register or pstate
-// CHECK-UNKNOWN: d503437f   msr   S0_3_C4_C3_3, xzr
+// CHECK-UNKNOWN: d503437f   smstart
 
 msr SVCRZA, #0
 // CHECK-INST: smstop za
 // CHECK-ENCODING: [0x7f,0x44,0x03,0xd5]
 // CHECK-ERROR: expected writable system register or pstate
-// CHECK-UNKNOWN: d503447f   msr   S0_3_C4_C4_3, xzr
+// CHECK-UNKNOWN: d503447f   smstop za
 
 msr SVCRZA, #1
 // CHECK-INST: smstart za
 // CHECK-ENCODING: [0x7f,0x45,0x03,0xd5]
 // CHECK-ERROR: expected writable system register or pstate
-// CHECK-UNKNOWN: d503457f   msr   S0_3_C4_C5_3, xzr
+// CHECK-UNKNOWN: d503457f   smstart za
 
 msr SVCRSMZA, #0
 // CHECK-INST: smstop
 // CHECK-ENCODING: [0x7f,0x46,0x03,0xd5]
 // CHECK-ERROR: expected writable system register or pstate
-// CHECK-UNKNOWN: d503467f   msr   S0_3_C4_C6_3, xzr
+// CHECK-UNKNOWN: d503467f   smstop
 
 msr SVCRSMZA, #1
 // CHECK-INST: smstart
 // CHECK-ENCODING: [0x7f,0x47,0x03,0xd5]
 // CHECK-ERROR: expected writable system register or pstate
-// CHECK-UNKNOWN: d503477f   msr   S0_3_C4_C7_3, xzr
+// CHECK-UNKNOWN: d503477f   smstart
 
 msr TPIDR2_EL0, x3
 // CHECK-INST: msr TPIDR2_EL0, x3


        


More information about the llvm-commits mailing list