[llvm] [win][aarch64] Add support for detecting the Host CPU on Arm64 Windows (PR #151596)

David Green via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 2 04:11:56 PDT 2025


================
@@ -1450,6 +1462,48 @@ StringRef sys::getHostCPUName() {
   return "generic";
 }
 
+#elif defined(_M_ARM64) || defined(_M_ARM64EC)
+
+union MIDR_EL1 {
+  uint64_t Raw;
+  struct _Parts {
+    uint64_t Revision : 4;
+    uint64_t Partnum : 12;
+    uint64_t Architecture : 4;
+    uint64_t Variant : 4;
+    uint64_t Implementer : 8;
+    uint64_t Reserved : 32;
+  } Parts;
+};
+
+StringRef sys::getHostCPUName() {
+  StringRef CPU = "generic";
+
+  // The "CP 4000" registry key contains a cached copy of the MIDR_EL1 register.
+  HKEY Key;
+  if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
+                    "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0,
+                    KEY_READ, &Key) == ERROR_SUCCESS) {
+    MIDR_EL1 RegValue;
+    DWORD ActualType;
+    DWORD RegValueSize = sizeof(RegValue);
+    if ((RegQueryValueExA(Key, "CP 4000", nullptr, &ActualType,
+                          (PBYTE)&RegValue, &RegValueSize) == ERROR_SUCCESS) &&
+        (ActualType == REG_QWORD) && RegValueSize == sizeof(RegValue)) {
+      auto Part = "0x" + utohexstr(RegValue.Parts.Partnum, /*LowerCase*/ true,
+                                   /*Width*/ 3);
+      CPU = detail::getHostCPUNameForARM(
+          "0x" + utohexstr(RegValue.Parts.Implementer, /*LowerCase*/ true,
----------------
davemgreen wrote:

Unfortunately I don't think the lowest or biggest part-number is always the biggest CPU. It will often be the little CPU in a system (which might not be the worst thing to pick, at least for scheduling). Otherwise we would probably have used it to get a more reliable order than the one that happens to be last in the list.

I think on linux it just picks the last one to match the old behaviour of looking through them all. But AFAUI from the few devices I have checked, the last ordered CPUs are often the bigger ones, so makes sense to pick if the big cpu is the preference. (I'm not sure how reliable that is on all devices though). The intent is to maybe use MatchBigLittle() in more places to be explicit about which cpu we are opting to optimize for, but that was added fairly recently.

https://github.com/llvm/llvm-project/pull/151596


More information about the llvm-commits mailing list