t.p.northover created this revision.
Herald added subscribers: hiraditya, kristof.beyls, mcrosier.
Herald added a project: All.
t.p.northover requested review of this revision.
Herald added projects: clang, LLVM.

The new variants like `dsb ishnxs` map naturally to CRm == {16, 20, 24, 28}, 
extending the existing space of immediates for `__builtin_arm_dsb`. This adds 
Clang and backend CodeGen support to emit them when processor support is 
present, and reasonable diagnostics when it's not.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D139182

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Basic/Targets/AArch64.cpp
  clang/lib/Basic/Targets/AArch64.h
  clang/lib/Sema/SemaChecking.cpp
  clang/test/Sema/builtins-arm64.c
  llvm/include/llvm/Support/AArch64TargetParser.def
  llvm/include/llvm/Support/AArch64TargetParser.h
  llvm/lib/Target/AArch64/AArch64InstrFormats.td
  llvm/lib/Target/AArch64/AArch64InstrInfo.td
  llvm/test/CodeGen/AArch64/dsb-xs.ll
  llvm/unittests/Support/TargetParserTest.cpp

Index: llvm/unittests/Support/TargetParserTest.cpp
===================================================================
--- llvm/unittests/Support/TargetParserTest.cpp
+++ llvm/unittests/Support/TargetParserTest.cpp
@@ -1541,7 +1541,7 @@
       AArch64::AEK_PERFMON, AArch64::AEK_SVE2p1,    AArch64::AEK_SME2p1,
       AArch64::AEK_B16B16,  AArch64::AEK_SMEF16F16, AArch64::AEK_CSSC,
       AArch64::AEK_RCPC3,   AArch64::AEK_THE,       AArch64::AEK_D128,
-      AArch64::AEK_LSE128,
+      AArch64::AEK_LSE128,  AArch64::AEK_XS,
   };
 
   std::vector<StringRef> Features;
Index: llvm/test/CodeGen/AArch64/dsb-xs.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/AArch64/dsb-xs.ll
@@ -0,0 +1,17 @@
+; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+xs %s -o - | FileCheck %s
+
+define void @test_barriers() {
+; CHECK-LABEL: test_barriers:
+
+; CHECK: dsb oshnxs
+; CHECK: dsb nshnxs
+; CHECK: dsb ishnxs
+; CHECK: dsb synxs
+
+  call void @llvm.aarch64.dsb(i32 16)
+  call void @llvm.aarch64.dsb(i32 20)
+  call void @llvm.aarch64.dsb(i32 24)
+  call void @llvm.aarch64.dsb(i32 28)
+  ret void
+}
+declare void @llvm.aarch64.dsb(i32)
Index: llvm/lib/Target/AArch64/AArch64InstrInfo.td
===================================================================
--- llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -1000,7 +1000,8 @@
   let Predicates = [HasTRACEV8_4];
 }
 
-def DSBnXS  : CRmSystemI<barrier_nxs_op, 0b001, "dsb"> {
+def DSBnXS  : CRmSystemI<barrier_nxs_op, 0b001, "dsb",
+                         [(int_aarch64_dsb (i32 imm32_nXS:$CRm))]> {
   let CRm{1-0}   = 0b11;
   let Inst{9-8}  = 0b10;
   let Predicates = [HasXS];
Index: llvm/lib/Target/AArch64/AArch64InstrFormats.td
===================================================================
--- llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -1021,6 +1021,14 @@
   let ParserMatchClass = Imm0_255Operand;
 }
 
+def DSBnXSXForm : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant((N->getZExtValue() & 0xc) | 3, SDLoc(N), MVT::i32);
+}]>;
+
+def imm32_nXS : ImmLeaf<i32, [{
+  return Imm == 16 || Imm == 20 || Imm == 24 || Imm == 28;
+}], DSBnXSXForm>;
+
 // An arithmetic shifter operand:
 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
 //  {5-0} - imm6
Index: llvm/include/llvm/Support/AArch64TargetParser.h
===================================================================
--- llvm/include/llvm/Support/AArch64TargetParser.h
+++ llvm/include/llvm/Support/AArch64TargetParser.h
@@ -82,6 +82,7 @@
   AEK_THE =         1ULL << 50, // FEAT_THE
   AEK_D128 =        1ULL << 51, // FEAT_D128
   AEK_LSE128 =      1ULL << 52, // FEAT_LSE128
+  AEK_XS =          1ULL << 53, // FEAT_XS
 };
 
 // Represents an extension that can be enabled with -march=<arch>+<extension>.
Index: llvm/include/llvm/Support/AArch64TargetParser.def
===================================================================
--- llvm/include/llvm/Support/AArch64TargetParser.def
+++ llvm/include/llvm/Support/AArch64TargetParser.def
@@ -47,21 +47,21 @@
               AArch64::AEK_SM4  | AArch64::AEK_SHA3 | AArch64::AEK_BF16    |
               AArch64::AEK_SHA2 | AArch64::AEK_AES  | AArch64::AEK_I8MM))
 AARCH64_ARCH(8, 7, AProfile, "armv8.7-a", ARMV8_7A, "+v8.7a",
-             (AArch64::AEK_CRC | AArch64::AEK_FP |
-              AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
-              AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
+             (AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_SIMD |
+              AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM |
+              AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_XS |
               AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_BF16 |
               AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_I8MM))
 AARCH64_ARCH(8, 8, AProfile, "armv8.8-a", ARMV8_8A, "+v8.8a",
-             (AArch64::AEK_CRC | AArch64::AEK_FP |
-              AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
-              AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
+             (AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_SIMD |
+              AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM |
+              AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_XS |
               AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_BF16 |
               AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_I8MM))
 AARCH64_ARCH(8, 9, AProfile, "armv8.9-a", ARMV8_9A, "+v8.9a",
-             (AArch64::AEK_CRC | AArch64::AEK_FP |
-              AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
-              AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
+             (AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_SIMD |
+              AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM |
+              AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_XS |
               AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_BF16 |
               AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_I8MM))
 AARCH64_ARCH(9, 0, AProfile, "armv9-a",   ARMV9A, "+v9a",
@@ -75,19 +75,19 @@
               AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
               AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2))
 AARCH64_ARCH(9, 2, AProfile, "armv9.2-a", ARMV9_2A, "+v9.2a",
-             (AArch64::AEK_CRC | AArch64::AEK_FP |
-              AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
-              AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
+             (AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_SIMD |
+              AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM |
+              AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_XS |
               AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2))
 AARCH64_ARCH(9, 3, AProfile, "armv9.3-a", ARMV9_3A, "+v9.3a",
-             (AArch64::AEK_CRC | AArch64::AEK_FP |
-              AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
-              AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
+             (AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_SIMD |
+              AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM |
+              AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_XS |
               AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2))
 AARCH64_ARCH(9, 4, AProfile, "armv9.4-a", ARMV9_4A, "+v9.4a",
-             (AArch64::AEK_CRC | AArch64::AEK_FP |
-              AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
-              AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
+             (AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_SIMD |
+              AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM |
+              AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_XS |
               AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2))
 // For v8-R, we do not enable crypto and align with GCC that enables a more
 // minimal set of optional architecture extensions.
@@ -155,6 +155,7 @@
 AARCH64_ARCH_EXT_NAME("the",          AArch64::AEK_THE,         "+the",          "-the")
 AARCH64_ARCH_EXT_NAME("d128",         AArch64::AEK_D128,        "+d128",         "-d128")
 AARCH64_ARCH_EXT_NAME("lse128",       AArch64::AEK_LSE128,      "+lse128",       "-lse128")
+AARCH64_ARCH_EXT_NAME("xs",           AArch64::AEK_XS,          "+xs",           "-xs")
 #undef AARCH64_ARCH_EXT_NAME
 
 #ifndef AARCH64_CPU_NAME
Index: clang/test/Sema/builtins-arm64.c
===================================================================
--- clang/test/Sema/builtins-arm64.c
+++ clang/test/Sema/builtins-arm64.c
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -triple arm64-apple-ios -fsyntax-only -verify %s
 // RUN: %clang_cc1 -triple arm64-apple-ios -DTEST1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -target-feature +xs -DXS -fsyntax-only -verify %s
 
 #ifdef TEST1
 void __clear_cache(void *start, void *end);
@@ -19,10 +20,20 @@
 
 void test_memory_barriers(void) {
   __builtin_arm_dmb(16); // expected-error-re {{argument value {{.*}} is outside the valid range}}
-  __builtin_arm_dsb(17); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+  __builtin_arm_dsb(17); // expected-error-re {{DSB argument value {{.*}} is outside valid set}}
   __builtin_arm_isb(18); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+
+#ifdef XS
+  __builtin_arm_dsb(16);
+  __builtin_arm_dsb(20);
+  __builtin_arm_dsb(24);
+  __builtin_arm_dsb(28);
+#else
+  __builtin_arm_dsb(20); // expected-error    {{DSB argument value 20 requires FEAT_XS support}}
+#endif
 }
 
+
 void test_prefetch(void) {
   __builtin_arm_prefetch(0, 2, 0, 0, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}}
   __builtin_arm_prefetch(0, 0, 3, 0, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}}
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -3271,13 +3271,27 @@
   if (CheckSVEBuiltinFunctionCall(BuiltinID, TheCall))
     return true;
 
+  if (BuiltinID == AArch64::BI__builtin_arm_dsb) {
+    llvm::APSInt Result;
+    if (SemaBuiltinConstantArg(TheCall, 0, Result))
+      return true;
+    if (Result >= 0 && Result <= 15)
+      return false;
+    else if (Result == 16 || Result == 20 || Result == 24 || Result == 28)
+      return TI.hasFeature("xs")
+                 ? false
+                 : Diag(TheCall->getBeginLoc(), diag::err_arm_invalid_dsb_xs)
+                       << Result.getSExtValue();
+    return Diag(TheCall->getBeginLoc(), diag::err_arm_invalid_dsb)
+           << Result.getSExtValue();
+  }
+
   // For intrinsics which take an immediate value as part of the instruction,
   // range check them here.
   unsigned i = 0, l = 0, u = 0;
   switch (BuiltinID) {
   default: return false;
   case AArch64::BI__builtin_arm_dmb:
-  case AArch64::BI__builtin_arm_dsb:
   case AArch64::BI__builtin_arm_isb: l = 0; u = 15; break;
   case AArch64::BI__builtin_arm_tcancel: l = 0; u = 65535; break;
   }
Index: clang/lib/Basic/Targets/AArch64.h
===================================================================
--- clang/lib/Basic/Targets/AArch64.h
+++ clang/lib/Basic/Targets/AArch64.h
@@ -55,6 +55,7 @@
   bool HasMOPS;
   bool HasD128;
   bool HasRCPC;
+  bool HasXS;
 
   const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A;
 
Index: clang/lib/Basic/Targets/AArch64.cpp
===================================================================
--- clang/lib/Basic/Targets/AArch64.cpp
+++ clang/lib/Basic/Targets/AArch64.cpp
@@ -515,6 +515,7 @@
     .Case("neon", FPU & NeonMode)
     .Cases("sve", "sve2", "sve2-bitperm", "sve2-aes", "sve2-sha3", "sve2-sm4", "f64mm", "f32mm", "i8mm", "bf16", FPU & SveMode)
     .Case("ls64", HasLS64)
+    .Case("xs", HasXS)
     .Default(false);
 }
 
@@ -563,6 +564,7 @@
   HasMOPS = false;
   HasD128 = false;
   HasRCPC = false;
+  HasXS = false;
 
   for (const auto &Feature : Features) {
     if (Feature == "+neon")
@@ -612,6 +614,8 @@
       HasCRC = true;
     if (Feature == "+rcpc")
       HasRCPC = true;
+    if (Feature == "+xs")
+      HasXS = true;
     if (Feature == "+aes")
       HasAES = true;
     if (Feature == "+sha2")
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9945,6 +9945,10 @@
   "%select{too many|too few}0 elements in vector initialization (expected %1 elements, have %2)">;
 def err_altivec_empty_initializer : Error<"expected initializer">;
 
+def err_arm_invalid_dsb : Error<
+  "DSB argument value %0 is outside valid set {0-15, 16, 20, 24, 28}">;
+def err_arm_invalid_dsb_xs : Error<
+  "DSB argument value %0 requires FEAT_XS support">;
 def err_invalid_neon_type_code : Error<
   "incompatible constant for this __builtin_neon function">;
 def err_argument_invalid_range : Error<
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D139182: AArch64: ad... Tim Northover via Phabricator via cfe-commits

Reply via email to