Tested on x86_64-darwin/linux(cascadelake), pushed to trunk, thanks
Iain

--- 8< ---

Darwin enables the avx512 state in XCR0 lazily which means that a
constructor querying it is unreliable.  However, the kernel will
correctly report the availability, so query that.

gcc/ChangeLog:

        * common/config/i386/cpuinfo.h (darwin_get_kernel_bool): New.
        (get_available_features): Query kernel for avx512 availability
        on Darwin.

Signed-off-by: Iain Sandoe <[email protected]>
---
 gcc/common/config/i386/cpuinfo.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index a689afabd3d..f433810457b 100644
--- a/gcc/common/config/i386/cpuinfo.h
+++ b/gcc/common/config/i386/cpuinfo.h
@@ -782,6 +782,17 @@ get_zhaoxin_cpu (struct __processor_model *cpu_model,
   return cpu;
 }
 
+#ifdef __APPLE__
+#include <sys/sysctl.h>
+/* Will return false if the queried state is either absent or 0.  */
+static inline int
+darwin_get_kernel_bool (const char *name)
+{
+  int val = 0; size_t len = sizeof (val);
+  return sysctlbyname (name, &val, &len, NULL, 0) == 0 && val != 0;
+}
+#endif
+
 /* ECX and EDX are output of CPUID at level one.  */
 static inline void
 get_available_features (struct __processor_model *cpu_model,
@@ -840,8 +851,14 @@ get_available_features (struct __processor_model 
*cpu_model,
       if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK)
        {
          avx_usable = 1;
+#ifdef __APPLE__
+         /* Darwin enables the avx512 XSAVE state lazily, so a constructor
+            that reads XCR0 is not reliable - query the kernel instead.  */
+         avx512_usable = darwin_get_kernel_bool ("hw.optional.avx512f");
+#else
          avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK)
                           == XCR_AVX512F_ENABLED_MASK);
+#endif
        }
       amx_usable = ((xcrlow & XCR_AMX_ENABLED_MASK)
                    == XCR_AMX_ENABLED_MASK);
-- 
2.50.1 (Apple Git-155)

Reply via email to