[PATCH] D158348: [clang][X86] Add __cpuidex function to cpuid.h

2023-08-22 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a subscriber: eandrews.
aaron.ballman added a comment.

@eandrews tested this patch out internally at Intel and it seems to work well 
for us (didn't break the internal tests that we had troubles with before). I 
think the changes here look reasonable, but I leave it to the original 
reviewers of https://reviews.llvm.org/D150646 to do the final sign-off.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158348/new/

https://reviews.llvm.org/D158348

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D158348: [clang][X86] Add __cpuidex function to cpuid.h

2023-08-19 Thread Aiden Grossman via Phabricator via cfe-commits
aidengrossman added reviewers: aaron.ballman, glandium, mstorsjo, craig.topper.
aidengrossman added a comment.

This is an updated version of https://reviews.llvm.org/D150646 that uses 
`__has_builtin` instead of checking for a definition of `_MSC_EXTENSIONS`. This 
fixes the cases that I have received so far and shouldn't cause any other 
issues.

There is one thing that needs some discussion: include order relating to 
`intrin.h`. When using a MSVC target triple with `-fms-extensions` (and maybe 
in other cases), `intrin.h` needs to be included to get the declaration of the 
built-in (or otherwise `__has_builtin` won't detect it and it will error out 
later). This means that the way the patch is setup currently `intrin.h` needs 
to be included before `cpuid.h`. The only way I see to fix this is to use the 
MSVC `__cpuidex` signature which drops the `static` keyword. This makes the 
implementation slightly different from the GCC implementation (where they 
include `static`), but it would allow us to declare the function outside of the 
preprocessor conditional in `cpuid.h` which would make `cpuid.h` 
include-order-agnostic again with respect to `intrin.h`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158348/new/

https://reviews.llvm.org/D158348

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D158348: [clang][X86] Add __cpuidex function to cpuid.h

2023-08-19 Thread Aiden Grossman via Phabricator via cfe-commits
aidengrossman created this revision.
Herald added a project: All.
aidengrossman requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added subscribers: cfe-commits, jplehr, sstefan1.
Herald added a project: clang.

MSVC has a __cpuidex function implemented to call the underlying cpuid
instruction which accepts a leaf, subleaf, and data array that the output
data is written into. This patch adds this functionality into clang
under the cpuid.h header. This also makes clang match GCC's behavior.
GCC has had __cpuidex in its cpuid.h since 2020.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D158348

Files:
  clang/lib/Headers/cpuid.h
  clang/test/Headers/__cpuidex_conflict.c
  clang/test/Headers/cpuid.c


Index: clang/test/Headers/cpuid.c
===
--- clang/test/Headers/cpuid.c
+++ clang/test/Headers/cpuid.c
@@ -6,14 +6,19 @@
 
 // CHECK-64: {{.*}} call { i32, i32, i32, i32 } asm "  xchgq  %rbx,${1:q}\0A 
cpuid\0A xchgq %rbx,${1:q}", 
"={ax},=r,={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}})
 // CHECK-64: {{.*}} call { i32, i32, i32, i32 } asm "  xchgq  %rbx,${1:q}\0A  
cpuid\0A  xchgq  %rbx,${1:q}", 
"={ax},=r,={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}, i32 
%{{[a-z0-9]+}})
+// CHECK-64: {{.*}} call { i32, i32, i32, i32 } asm "  xchgq  %rbx,${1:q}\0A  
cpuid\0A  xchgq  %rbx,${1:q}", 
"={ax},=r,={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}, i32 
%{{[a-z0-9]+}})
 
 // CHECK-32: {{.*}} call { i32, i32, i32, i32 } asm "cpuid", 
"={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}})
 // CHECK-32: {{.*}} call { i32, i32, i32, i32 } asm "cpuid", 
"={ax},={bx},={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}, 
i32 %{{[a-z0-9]+}})
+// CHECK-32: {{.*}} call { i32, i32, i32, i32 } asm "cpuid", 
"={ax},={bx},={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}, 
i32 %{{[a-z0-9]+}})
 
 unsigned eax0, ebx0, ecx0, edx0;
 unsigned eax1, ebx1, ecx1, edx1;
 
+int cpuid_info[4];
+
 void test_cpuid(unsigned level, unsigned count) {
   __cpuid(level, eax1, ebx1, ecx1, edx1);
   __cpuid_count(level, count, eax0, ebx0, ecx0, edx0);
+  __cpuidex(cpuid_info, level, count);
 }
Index: clang/test/Headers/__cpuidex_conflict.c
===
--- /dev/null
+++ clang/test/Headers/__cpuidex_conflict.c
@@ -0,0 +1,22 @@
+// Make sure that __cpuidex in cpuid.h doesn't conflict with the MS
+// extensions built in by ensuring compilation succeeds:
+// RUN: %clang_cc1 %s -ffreestanding -fms-extensions -fms-compatibility \
+// RUN:  -fms-compatibility-version=19.00 -triple x86_64-pc-windows-msvc 
-emit-llvm -o -
+// %clang_cc1 %s -ffreestanding -triple x86_64-w64-windows-gnu -fms-extensions 
-emit-llvm -o -
+// RUN: %clang_cc1 %s -ffreestanding -fopenmp -fopenmp-is-target-device 
-aux-triple x86_64-unknown-linux-gnu
+
+typedef __SIZE_TYPE__ size_t;
+
+// We declare __cpuidex here as where the buitlin should be exposed (MSVC), the
+// declaration is in , but  is not available from all the
+// targets that are being tested here.
+void __cpuidex (int[4], int, int);
+
+#include 
+
+int cpuid_info[4];
+
+void test_cpuidex(unsigned level, unsigned count) {
+  __cpuidex(cpuid_info, level, count);
+}
+
Index: clang/lib/Headers/cpuid.h
===
--- clang/lib/Headers/cpuid.h
+++ clang/lib/Headers/cpuid.h
@@ -328,4 +328,14 @@
 return 1;
 }
 
+// In some configurations, __cpuidex is defined as a builtin (primarily
+// -fms-extensions) which will conflict with the __cpuidex definition below.
+#if !(__has_builtin(__cpuidex))
+static __inline void __cpuidex (int __cpu_info[4], int __leaf, int __subleaf)
+{
+  __cpuid_count(__leaf, __subleaf, __cpu_info[0], __cpu_info[1], __cpu_info[2],
+__cpu_info[3]);
+}
+#endif
+
 #endif /* __CPUID_H */


Index: clang/test/Headers/cpuid.c
===
--- clang/test/Headers/cpuid.c
+++ clang/test/Headers/cpuid.c
@@ -6,14 +6,19 @@
 
 // CHECK-64: {{.*}} call { i32, i32, i32, i32 } asm "  xchgq  %rbx,${1:q}\0A cpuid\0A xchgq %rbx,${1:q}", "={ax},=r,={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}})
 // CHECK-64: {{.*}} call { i32, i32, i32, i32 } asm "  xchgq  %rbx,${1:q}\0A  cpuid\0A  xchgq  %rbx,${1:q}", "={ax},=r,={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}, i32 %{{[a-z0-9]+}})
+// CHECK-64: {{.*}} call { i32, i32, i32, i32 } asm "  xchgq  %rbx,${1:q}\0A  cpuid\0A  xchgq  %rbx,${1:q}", "={ax},=r,={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}}, i32 %{{[a-z0-9]+}})
 
 // CHECK-32: {{.*}} call { i32, i32, i32, i32 } asm "cpuid", "={ax},={bx},={cx},={dx},0,~{dirflag},~{fpsr},~{flags}"(i32 %{{[a-z0-9]+}})
 // CHECK-32: {{.*}} call { i32, i32, i32, i32 } asm "cpuid",