[compiler-rt] [AArch64][compiler-rt] Add a function returning the current vector length (PR #92921)

Kerry McLaughlin via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 3 06:09:32 PDT 2024


https://github.com/kmclaughlin-arm updated https://github.com/llvm/llvm-project/pull/92921

>From 1038d54920dbfc6dbdad0842074f8dba463a9f35 Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Tue, 21 May 2024 09:54:52 +0000
Subject: [PATCH 1/6] [AArch64][compiler-rt] Add a function returning the
 current vector length

get_runtime_vl emits a cntd instruction if SVE is available at runtime,
otherwise it will return 0.
---
 .../lib/builtins/aarch64/sme-abi-init.c       | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/compiler-rt/lib/builtins/aarch64/sme-abi-init.c b/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
index b6ee12170d56d..331ec4b634b5b 100644
--- a/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
+++ b/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
@@ -2,6 +2,8 @@
 // See https://llvm.org/LICENSE.txt for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
+#include "../cpu_model/aarch64.c"
+
 __attribute__((visibility("hidden"), nocommon))
 _Bool __aarch64_has_sme_and_tpidr2_el0;
 
@@ -50,3 +52,26 @@ __attribute__((constructor(90)))
 static void init_aarch64_has_sme(void) {
   __aarch64_has_sme_and_tpidr2_el0 = has_sme();
 }
+
+#if __GNUC__ >= 9
+#pragma GCC diagnostic ignored "-Wprio-ctor-dtor"
+#endif
+__attribute__((constructor(90)))
+void get_aarch64_cpu_features(void) {
+  if (!__aarch64_cpu_features.features)
+    __init_cpu_features();
+}
+
+__attribute__((target("sve")))
+long emit_cntd(void) {
+  long vl;
+  __asm__ __volatile__("cntd %0" : "=r" (vl));
+  return vl;
+}
+
+long get_runtime_vl(void) {
+  if (__aarch64_cpu_features.features & (1ULL << FEAT_SVE))
+    return emit_cntd();
+  else
+    return 0;
+}

>From 2baec75cb3ec90057b241b7c835699c93da7c149 Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Tue, 21 May 2024 14:57:47 +0000
Subject: [PATCH 2/6] - Run clang-format

---
 compiler-rt/lib/builtins/aarch64/sme-abi-init.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/compiler-rt/lib/builtins/aarch64/sme-abi-init.c b/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
index 331ec4b634b5b..f8a47773b0a6e 100644
--- a/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
+++ b/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
@@ -56,16 +56,14 @@ static void init_aarch64_has_sme(void) {
 #if __GNUC__ >= 9
 #pragma GCC diagnostic ignored "-Wprio-ctor-dtor"
 #endif
-__attribute__((constructor(90)))
-void get_aarch64_cpu_features(void) {
+__attribute__((constructor(90))) void get_aarch64_cpu_features(void) {
   if (!__aarch64_cpu_features.features)
     __init_cpu_features();
 }
 
-__attribute__((target("sve")))
-long emit_cntd(void) {
+__attribute__((target("sve"))) long emit_cntd(void) {
   long vl;
-  __asm__ __volatile__("cntd %0" : "=r" (vl));
+  __asm__ __volatile__("cntd %0" : "=r"(vl));
   return vl;
 }
 

>From 75c2ae90b58b6a0646dcd1a4aa1e902ebbabd060 Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Wed, 22 May 2024 09:29:32 +0000
Subject: [PATCH 3/6] - Changes based on support routine added to the ABI
 document, see:   https://github.com/ARM-software/abi-aa/pull/263   - Renamed
 get_runtime_vl to __arm_get_current_vg   - Also return VG if currently in
 streaming-mode

- Added static to get_aarch64_cpu_features

- Added aarch64.h and included in sme-abi-init.c
---
 .../lib/builtins/aarch64/sme-abi-init.c       | 29 +++---
 compiler-rt/lib/builtins/cpu_model/aarch64.c  | 72 +--------------
 compiler-rt/lib/builtins/cpu_model/aarch64.h  | 90 +++++++++++++++++++
 3 files changed, 110 insertions(+), 81 deletions(-)
 create mode 100644 compiler-rt/lib/builtins/cpu_model/aarch64.h

diff --git a/compiler-rt/lib/builtins/aarch64/sme-abi-init.c b/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
index f8a47773b0a6e..35a6ce26eb6f3 100644
--- a/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
+++ b/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
@@ -2,7 +2,8 @@
 // See https://llvm.org/LICENSE.txt for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
-#include "../cpu_model/aarch64.c"
+#include "../cpu_model/aarch64.h"
+#include <arm_sme.h>
 
 __attribute__((visibility("hidden"), nocommon))
 _Bool __aarch64_has_sme_and_tpidr2_el0;
@@ -56,20 +57,24 @@ static void init_aarch64_has_sme(void) {
 #if __GNUC__ >= 9
 #pragma GCC diagnostic ignored "-Wprio-ctor-dtor"
 #endif
-__attribute__((constructor(90))) void get_aarch64_cpu_features(void) {
-  if (!__aarch64_cpu_features.features)
+__attribute__((constructor(90))) static void get_aarch64_cpu_features(void) {
+  if (!get_features())
     __init_cpu_features();
 }
 
-__attribute__((target("sve"))) long emit_cntd(void) {
-  long vl;
-  __asm__ __volatile__("cntd %0" : "=r"(vl));
-  return vl;
-}
+extern bool __arm_in_streaming_mode(void) __arm_streaming_compatible;
 
-long get_runtime_vl(void) {
-  if (__aarch64_cpu_features.features & (1ULL << FEAT_SVE))
-    return emit_cntd();
-  else
+__attribute__((target("sve"))) long
+__arm_get_current_vg(void) __arm_streaming_compatible {
+  bool HasSVE = get_features() & (1ULL << FEAT_SVE);
+  if (!HasSVE && !has_sme())
     return 0;
+
+  if (HasSVE || __arm_in_streaming_mode()) {
+    long vl;
+    __asm__ __volatile__("cntd %0" : "=r"(vl));
+    return vl;
+  }
+
+  return 0;
 }
diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64.c b/compiler-rt/lib/builtins/cpu_model/aarch64.c
index 17bddfca46f09..43814fc6d7986 100644
--- a/compiler-rt/lib/builtins/cpu_model/aarch64.c
+++ b/compiler-rt/lib/builtins/cpu_model/aarch64.c
@@ -12,7 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "cpu_model.h"
+#include "aarch64.h"
 
 #if !defined(__aarch64__)
 #error This file is intended only for aarch64-based targets
@@ -53,74 +53,6 @@ _Bool __aarch64_have_lse_atomics
 #endif
 
 #if !defined(DISABLE_AARCH64_FMV)
-// CPUFeatures must correspond to the same AArch64 features in
-// AArch64TargetParser.h
-enum CPUFeatures {
-  FEAT_RNG,
-  FEAT_FLAGM,
-  FEAT_FLAGM2,
-  FEAT_FP16FML,
-  FEAT_DOTPROD,
-  FEAT_SM4,
-  FEAT_RDM,
-  FEAT_LSE,
-  FEAT_FP,
-  FEAT_SIMD,
-  FEAT_CRC,
-  FEAT_SHA1,
-  FEAT_SHA2,
-  FEAT_SHA3,
-  FEAT_AES,
-  FEAT_PMULL,
-  FEAT_FP16,
-  FEAT_DIT,
-  FEAT_DPB,
-  FEAT_DPB2,
-  FEAT_JSCVT,
-  FEAT_FCMA,
-  FEAT_RCPC,
-  FEAT_RCPC2,
-  FEAT_FRINTTS,
-  FEAT_DGH,
-  FEAT_I8MM,
-  FEAT_BF16,
-  FEAT_EBF16,
-  FEAT_RPRES,
-  FEAT_SVE,
-  FEAT_SVE_BF16,
-  FEAT_SVE_EBF16,
-  FEAT_SVE_I8MM,
-  FEAT_SVE_F32MM,
-  FEAT_SVE_F64MM,
-  FEAT_SVE2,
-  FEAT_SVE_AES,
-  FEAT_SVE_PMULL128,
-  FEAT_SVE_BITPERM,
-  FEAT_SVE_SHA3,
-  FEAT_SVE_SM4,
-  FEAT_SME,
-  FEAT_MEMTAG,
-  FEAT_MEMTAG2,
-  FEAT_MEMTAG3,
-  FEAT_SB,
-  FEAT_PREDRES,
-  FEAT_SSBS,
-  FEAT_SSBS2,
-  FEAT_BTI,
-  FEAT_LS64,
-  FEAT_LS64_V,
-  FEAT_LS64_ACCDATA,
-  FEAT_WFXT,
-  FEAT_SME_F64,
-  FEAT_SME_I64,
-  FEAT_SME2,
-  FEAT_RCPC3,
-  FEAT_MOPS,
-  FEAT_MAX,
-  FEAT_EXT = 62, // Reserved to indicate presence of additional features field
-                 // in __aarch64_cpu_features
-  FEAT_INIT      // Used as flag of features initialization completion
-};
 
 // Architecture features used
 // in Function Multi Versioning
@@ -129,6 +61,8 @@ struct {
   // As features grows new fields could be added
 } __aarch64_cpu_features __attribute__((visibility("hidden"), nocommon));
 
+long long get_features(void) { return __aarch64_cpu_features.features; }
+
 // The formatter wants to re-order these includes, but doing so is incorrect:
 // clang-format off
 #if defined(__APPLE__)
diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64.h b/compiler-rt/lib/builtins/cpu_model/aarch64.h
new file mode 100644
index 0000000000000..c7f8bcd176b5b
--- /dev/null
+++ b/compiler-rt/lib/builtins/cpu_model/aarch64.h
@@ -0,0 +1,90 @@
+//===-- cpu_model/aarch64.h --------------------------------------------- -===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "cpu_model.h"
+
+#if !defined(__aarch64__)
+#error This file is intended only for aarch64-based targets
+#endif
+
+#if !defined(DISABLE_AARCH64_FMV)
+
+// CPUFeatures must correspond to the same AArch64 features in
+// AArch64TargetParser.h
+enum CPUFeatures {
+  FEAT_RNG,
+  FEAT_FLAGM,
+  FEAT_FLAGM2,
+  FEAT_FP16FML,
+  FEAT_DOTPROD,
+  FEAT_SM4,
+  FEAT_RDM,
+  FEAT_LSE,
+  FEAT_FP,
+  FEAT_SIMD,
+  FEAT_CRC,
+  FEAT_SHA1,
+  FEAT_SHA2,
+  FEAT_SHA3,
+  FEAT_AES,
+  FEAT_PMULL,
+  FEAT_FP16,
+  FEAT_DIT,
+  FEAT_DPB,
+  FEAT_DPB2,
+  FEAT_JSCVT,
+  FEAT_FCMA,
+  FEAT_RCPC,
+  FEAT_RCPC2,
+  FEAT_FRINTTS,
+  FEAT_DGH,
+  FEAT_I8MM,
+  FEAT_BF16,
+  FEAT_EBF16,
+  FEAT_RPRES,
+  FEAT_SVE,
+  FEAT_SVE_BF16,
+  FEAT_SVE_EBF16,
+  FEAT_SVE_I8MM,
+  FEAT_SVE_F32MM,
+  FEAT_SVE_F64MM,
+  FEAT_SVE2,
+  FEAT_SVE_AES,
+  FEAT_SVE_PMULL128,
+  FEAT_SVE_BITPERM,
+  FEAT_SVE_SHA3,
+  FEAT_SVE_SM4,
+  FEAT_SME,
+  FEAT_MEMTAG,
+  FEAT_MEMTAG2,
+  FEAT_MEMTAG3,
+  FEAT_SB,
+  FEAT_PREDRES,
+  FEAT_SSBS,
+  FEAT_SSBS2,
+  FEAT_BTI,
+  FEAT_LS64,
+  FEAT_LS64_V,
+  FEAT_LS64_ACCDATA,
+  FEAT_WFXT,
+  FEAT_SME_F64,
+  FEAT_SME_I64,
+  FEAT_SME2,
+  FEAT_RCPC3,
+  FEAT_MOPS,
+  FEAT_MAX,
+  FEAT_EXT = 62, // Reserved to indicate presence of additional features field
+                 // in __aarch64_cpu_features
+  FEAT_INIT      // Used as flag of features initialization completion
+};
+
+long long get_features(void);
+
+void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void);
+
+#endif // !defined(DISABLE_AARCH64_FMV)

>From 455bb3af66b9ebc4da4af3eaadaad4b78662ac9d Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Thu, 30 May 2024 15:15:09 +0000
Subject: [PATCH 4/6] - Replaced use of __arm_in_streaming_mode from arm_sme.h
 with __arm_sme_state,   to check if currently in streaming mode.

---
 compiler-rt/lib/builtins/aarch64/sme-abi-init.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/compiler-rt/lib/builtins/aarch64/sme-abi-init.c b/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
index 35a6ce26eb6f3..96315c65e54ee 100644
--- a/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
+++ b/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
@@ -3,7 +3,6 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
 #include "../cpu_model/aarch64.h"
-#include <arm_sme.h>
 
 __attribute__((visibility("hidden"), nocommon))
 _Bool __aarch64_has_sme_and_tpidr2_el0;
@@ -62,15 +61,22 @@ __attribute__((constructor(90))) static void get_aarch64_cpu_features(void) {
     __init_cpu_features();
 }
 
-extern bool __arm_in_streaming_mode(void) __arm_streaming_compatible;
+struct SME_STATE {
+  long PSTATE;
+  long TPIDR2_EL0;
+};
+
+extern struct SME_STATE __arm_sme_state(void) __arm_streaming_compatible;
 
 __attribute__((target("sve"))) long
 __arm_get_current_vg(void) __arm_streaming_compatible {
+  struct SME_STATE State = __arm_sme_state();
   bool HasSVE = get_features() & (1ULL << FEAT_SVE);
+
   if (!HasSVE && !has_sme())
     return 0;
 
-  if (HasSVE || __arm_in_streaming_mode()) {
+  if (HasSVE || (State.PSTATE & 1)) {
     long vl;
     __asm__ __volatile__("cntd %0" : "=r"(vl));
     return vl;

>From 5edc4052417616de1cb9883ed85fd7206eb56070 Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Fri, 31 May 2024 10:39:25 +0000
Subject: [PATCH 5/6] - Renamed get_features to __get_aarch64_features in
 aarch64.h

---
 compiler-rt/lib/builtins/aarch64/sme-abi-init.c | 4 ++--
 compiler-rt/lib/builtins/cpu_model/aarch64.c    | 4 +++-
 compiler-rt/lib/builtins/cpu_model/aarch64.h    | 2 +-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/compiler-rt/lib/builtins/aarch64/sme-abi-init.c b/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
index 96315c65e54ee..b77de6227fb30 100644
--- a/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
+++ b/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
@@ -57,7 +57,7 @@ static void init_aarch64_has_sme(void) {
 #pragma GCC diagnostic ignored "-Wprio-ctor-dtor"
 #endif
 __attribute__((constructor(90))) static void get_aarch64_cpu_features(void) {
-  if (!get_features())
+  if (!__get_aarch64_features())
     __init_cpu_features();
 }
 
@@ -71,7 +71,7 @@ extern struct SME_STATE __arm_sme_state(void) __arm_streaming_compatible;
 __attribute__((target("sve"))) long
 __arm_get_current_vg(void) __arm_streaming_compatible {
   struct SME_STATE State = __arm_sme_state();
-  bool HasSVE = get_features() & (1ULL << FEAT_SVE);
+  bool HasSVE = __get_aarch64_features() & (1ULL << FEAT_SVE);
 
   if (!HasSVE && !has_sme())
     return 0;
diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64.c b/compiler-rt/lib/builtins/cpu_model/aarch64.c
index 43814fc6d7986..37c0ea06b2b56 100644
--- a/compiler-rt/lib/builtins/cpu_model/aarch64.c
+++ b/compiler-rt/lib/builtins/cpu_model/aarch64.c
@@ -61,7 +61,9 @@ struct {
   // As features grows new fields could be added
 } __aarch64_cpu_features __attribute__((visibility("hidden"), nocommon));
 
-long long get_features(void) { return __aarch64_cpu_features.features; }
+long long __get_aarch64_features(void) {
+  return __aarch64_cpu_features.features;
+}
 
 // The formatter wants to re-order these includes, but doing so is incorrect:
 // clang-format off
diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64.h b/compiler-rt/lib/builtins/cpu_model/aarch64.h
index c7f8bcd176b5b..1e99797e64326 100644
--- a/compiler-rt/lib/builtins/cpu_model/aarch64.h
+++ b/compiler-rt/lib/builtins/cpu_model/aarch64.h
@@ -83,7 +83,7 @@ enum CPUFeatures {
   FEAT_INIT      // Used as flag of features initialization completion
 };
 
-long long get_features(void);
+long long __get_aarch64_features(void);
 
 void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void);
 

>From 6a0a1fcd9b5a06acec197f51edd2e2cd40eb4e9c Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Mon, 3 Jun 2024 08:30:51 +0000
Subject: [PATCH 6/6] - Removed CONSTRUCTOR_ATTRIBUTE from __init_cpu_features
 declaration.

- Removed __get_aarch64_features.

- Split out changes for __arm_get_current_vg into a new file (sme-abi-vg.c)
  and removed from sme-abi-init.c.
---
 compiler-rt/lib/builtins/CMakeLists.txt       |  2 +-
 .../lib/builtins/aarch64/sme-abi-init.c       | 34 --------------
 compiler-rt/lib/builtins/aarch64/sme-abi-vg.c | 45 +++++++++++++++++++
 compiler-rt/lib/builtins/cpu_model/aarch64.c  |  4 --
 compiler-rt/lib/builtins/cpu_model/aarch64.h  |  4 +-
 5 files changed, 47 insertions(+), 42 deletions(-)
 create mode 100644 compiler-rt/lib/builtins/aarch64/sme-abi-vg.c

diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt
index f9611574a562b..9a97e597e1c6b 100644
--- a/compiler-rt/lib/builtins/CMakeLists.txt
+++ b/compiler-rt/lib/builtins/CMakeLists.txt
@@ -562,7 +562,7 @@ set(aarch64_SOURCES
 )
 
 if(COMPILER_RT_HAS_AARCH64_SME AND COMPILER_RT_HAS_FNO_BUILTIN_FLAG AND (COMPILER_RT_HAS_AUXV OR COMPILER_RT_BAREMETAL_BUILD))
-  list(APPEND aarch64_SOURCES aarch64/sme-abi.S aarch64/sme-abi-init.c aarch64/sme-libc-routines.c)
+  list(APPEND aarch64_SOURCES aarch64/sme-abi.S aarch64/sme-abi-init.c aarch64/sme-abi-vg.c aarch64/sme-libc-routines.c)
   message(STATUS "AArch64 SME ABI routines enabled")
   set_source_files_properties(aarch64/sme-libc-routines.c PROPERTIES COMPILE_FLAGS "-fno-builtin")
 else()
diff --git a/compiler-rt/lib/builtins/aarch64/sme-abi-init.c b/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
index b77de6227fb30..b6ee12170d56d 100644
--- a/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
+++ b/compiler-rt/lib/builtins/aarch64/sme-abi-init.c
@@ -2,8 +2,6 @@
 // See https://llvm.org/LICENSE.txt for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
-#include "../cpu_model/aarch64.h"
-
 __attribute__((visibility("hidden"), nocommon))
 _Bool __aarch64_has_sme_and_tpidr2_el0;
 
@@ -52,35 +50,3 @@ __attribute__((constructor(90)))
 static void init_aarch64_has_sme(void) {
   __aarch64_has_sme_and_tpidr2_el0 = has_sme();
 }
-
-#if __GNUC__ >= 9
-#pragma GCC diagnostic ignored "-Wprio-ctor-dtor"
-#endif
-__attribute__((constructor(90))) static void get_aarch64_cpu_features(void) {
-  if (!__get_aarch64_features())
-    __init_cpu_features();
-}
-
-struct SME_STATE {
-  long PSTATE;
-  long TPIDR2_EL0;
-};
-
-extern struct SME_STATE __arm_sme_state(void) __arm_streaming_compatible;
-
-__attribute__((target("sve"))) long
-__arm_get_current_vg(void) __arm_streaming_compatible {
-  struct SME_STATE State = __arm_sme_state();
-  bool HasSVE = __get_aarch64_features() & (1ULL << FEAT_SVE);
-
-  if (!HasSVE && !has_sme())
-    return 0;
-
-  if (HasSVE || (State.PSTATE & 1)) {
-    long vl;
-    __asm__ __volatile__("cntd %0" : "=r"(vl));
-    return vl;
-  }
-
-  return 0;
-}
diff --git a/compiler-rt/lib/builtins/aarch64/sme-abi-vg.c b/compiler-rt/lib/builtins/aarch64/sme-abi-vg.c
new file mode 100644
index 0000000000000..e384ab7f87c46
--- /dev/null
+++ b/compiler-rt/lib/builtins/aarch64/sme-abi-vg.c
@@ -0,0 +1,45 @@
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#include "../cpu_model/aarch64.h"
+
+struct FEATURES {
+  long long features;
+};
+
+extern struct FEATURES __aarch64_cpu_features;
+
+struct SME_STATE {
+  long PSTATE;
+  long TPIDR2_EL0;
+};
+
+extern struct SME_STATE __arm_sme_state(void) __arm_streaming_compatible;
+
+extern bool __aarch64_has_sme_and_tpidr2_el0;
+
+#if __GNUC__ >= 9
+#pragma GCC diagnostic ignored "-Wprio-ctor-dtor"
+#endif
+__attribute__((constructor(90))) static void get_aarch64_cpu_features(void) {
+  if (!__aarch64_cpu_features.features)
+    __init_cpu_features();
+}
+
+__attribute__((target("sve"))) long
+__arm_get_current_vg(void) __arm_streaming_compatible {
+  struct SME_STATE State = __arm_sme_state();
+  bool HasSVE = __aarch64_cpu_features.features & (1ULL << FEAT_SVE);
+
+  if (!HasSVE && !__aarch64_has_sme_and_tpidr2_el0)
+    return 0;
+
+  if (HasSVE || (State.PSTATE & 1)) {
+    long vl;
+    __asm__ __volatile__("cntd %0" : "=r"(vl));
+    return vl;
+  }
+
+  return 0;
+}
diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64.c b/compiler-rt/lib/builtins/cpu_model/aarch64.c
index 37c0ea06b2b56..b868caa991b2e 100644
--- a/compiler-rt/lib/builtins/cpu_model/aarch64.c
+++ b/compiler-rt/lib/builtins/cpu_model/aarch64.c
@@ -61,10 +61,6 @@ struct {
   // As features grows new fields could be added
 } __aarch64_cpu_features __attribute__((visibility("hidden"), nocommon));
 
-long long __get_aarch64_features(void) {
-  return __aarch64_cpu_features.features;
-}
-
 // The formatter wants to re-order these includes, but doing so is incorrect:
 // clang-format off
 #if defined(__APPLE__)
diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64.h b/compiler-rt/lib/builtins/cpu_model/aarch64.h
index 1e99797e64326..15d5300da53ba 100644
--- a/compiler-rt/lib/builtins/cpu_model/aarch64.h
+++ b/compiler-rt/lib/builtins/cpu_model/aarch64.h
@@ -83,8 +83,6 @@ enum CPUFeatures {
   FEAT_INIT      // Used as flag of features initialization completion
 };
 
-long long __get_aarch64_features(void);
-
-void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void);
+void __init_cpu_features(void);
 
 #endif // !defined(DISABLE_AARCH64_FMV)



More information about the llvm-commits mailing list