[clang] [clang][X86] Add __cpuidex function to cpuid.h (PR #97785)
https://github.com/boomanaiden154 closed https://github.com/llvm/llvm-project/pull/97785 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][X86] Add __cpuidex function to cpuid.h (PR #97785)
https://github.com/boomanaiden154 updated https://github.com/llvm/llvm-project/pull/97785 >From 38325cbf03e5013056dfc1b7939ec7c9738f9fe2 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Sat, 19 Aug 2023 13:37:21 -0700 Subject: [PATCH 1/2] [clang][X86] Add __cpuidex function to cpuid.h 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. This patch diverges from the gcc behavior slightly bynot marking __cpuidex as static. If __cpuidex is marked as static, then this differs from the signature used by MSVC (or at least what clang uses for MSVC), which can cause include ordering issues if intrin.h (which contains a declaration for __cpuidex) occurs before cpuid.h is included. --- clang/lib/Headers/cpuid.h | 10 ++ clang/test/Headers/__cpuidex_conflict.c | 22 ++ clang/test/Headers/cpuid.c | 5 + 3 files changed, 37 insertions(+) create mode 100644 clang/test/Headers/__cpuidex_conflict.c diff --git a/clang/lib/Headers/cpuid.h b/clang/lib/Headers/cpuid.h index bb7692efb78ff..cd55410cda8b7 100644 --- a/clang/lib/Headers/cpuid.h +++ b/clang/lib/Headers/cpuid.h @@ -339,4 +339,14 @@ static __inline int __get_cpuid_count (unsigned int __leaf, 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 */ diff --git a/clang/test/Headers/__cpuidex_conflict.c b/clang/test/Headers/__cpuidex_conflict.c new file mode 100644 index 0..8687a6aa2f897 --- /dev/null +++ b/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); +} + diff --git a/clang/test/Headers/cpuid.c b/clang/test/Headers/cpuid.c index 7e485495c1066..6ed12eca7a61d 100644 --- a/clang/test/Headers/cpuid.c +++ b/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); } >From 2afb49b803f291015f5049b811065b80858c07be Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Thu, 11 Jul 2024 22:53:06 + Subject: [PATCH 2/2] Format --- clang/lib/Headers/cpuid.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Headers/cpuid.h b/clang/lib/Headers/cpuid.h index cd55410cda8b7..82d995f1b966a 100644 --- a/clang/lib/Headers/cpuid.h +++ b/c
[clang] [clang][X86] Add __cpuidex function to cpuid.h (PR #97785)
https://github.com/boomanaiden154 edited https://github.com/llvm/llvm-project/pull/97785 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][X86] Add __cpuidex function to cpuid.h (PR #97785)
https://github.com/mstorsjo approved this pull request. LGTM, let’s reland this https://github.com/llvm/llvm-project/pull/97785 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][X86] Add __cpuidex function to cpuid.h (PR #97785)
boomanaiden154 wrote: > Thanks - I think this is fine with me. In > https://github.com/mingw-w64/mingw-w64/commit/a4c0c1d00d140d69a2c72f6ca0d49c91bdb2b08c > we adjusted the mingw-w64 headers in anticipation that this gets merged in > Clang 19, so it'd be good to have it settled before the 19.x branch gets made. Sounds good. Assuming there aren't any objections, I'll try and land this on Wednesday given it's just a reland, has been approved in the past, and the remaining (identified) issues have been signed off on phabricator. That should give time in case anyone has comments but still give a reasonable enough time frame to ensure it sticks for clang 19. https://github.com/llvm/llvm-project/pull/97785 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][X86] Add __cpuidex function to cpuid.h (PR #97785)
mstorsjo wrote: Thanks - I think this is fine with me. In https://github.com/mingw-w64/mingw-w64/commit/a4c0c1d00d140d69a2c72f6ca0d49c91bdb2b08c we adjusted the mingw-w64 headers in anticipation that this gets merged in Clang 19, so it'd be good to have it settled before the 19.x branch gets made. https://github.com/llvm/llvm-project/pull/97785 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][X86] Add __cpuidex function to cpuid.h (PR #97785)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 9e211744b82a72e08c137f75b1c671713e2891af 38325cbf03e5013056dfc1b7939ec7c9738f9fe2 -- clang/test/Headers/__cpuidex_conflict.c clang/lib/Headers/cpuid.h clang/test/Headers/cpuid.c `` View the diff from clang-format here. ``diff diff --git a/clang/lib/Headers/cpuid.h b/clang/lib/Headers/cpuid.h index cd55410cda..82d995f1b9 100644 --- a/clang/lib/Headers/cpuid.h +++ b/clang/lib/Headers/cpuid.h @@ -342,8 +342,7 @@ static __inline int __get_cpuid_count (unsigned int __leaf, // 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) -{ +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]); } `` https://github.com/llvm/llvm-project/pull/97785 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][X86] Add __cpuidex function to cpuid.h (PR #97785)
llvmbot wrote: @llvm/pr-subscribers-backend-x86 Author: Aiden Grossman (boomanaiden154) Changes 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. This patch diverges from the gcc behavior slightly bynot marking __cpuidex as static. If __cpuidex is marked as static, then this differs from the signature used by MSVC (or at least what clang uses for MSVC), which can cause include ordering issues if intrin.h (which contains a declaration for __cpuidex) occurs before cpuid.h is included. This is another attempt to land https://reviews.llvm.org/D158348. --- Full diff: https://github.com/llvm/llvm-project/pull/97785.diff 3 Files Affected: - (modified) clang/lib/Headers/cpuid.h (+10) - (added) clang/test/Headers/__cpuidex_conflict.c (+22) - (modified) clang/test/Headers/cpuid.c (+5) ``diff diff --git a/clang/lib/Headers/cpuid.h b/clang/lib/Headers/cpuid.h index bb7692efb78ffe..cd55410cda8b7c 100644 --- a/clang/lib/Headers/cpuid.h +++ b/clang/lib/Headers/cpuid.h @@ -339,4 +339,14 @@ static __inline int __get_cpuid_count (unsigned int __leaf, 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 */ diff --git a/clang/test/Headers/__cpuidex_conflict.c b/clang/test/Headers/__cpuidex_conflict.c new file mode 100644 index 00..8687a6aa2f897a --- /dev/null +++ b/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); +} + diff --git a/clang/test/Headers/cpuid.c b/clang/test/Headers/cpuid.c index 7e485495c10665..6ed12eca7a61d4 100644 --- a/clang/test/Headers/cpuid.c +++ b/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); } `` https://github.com/llvm/llvm-project/pull/97785 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][X86] Add __cpuidex function to cpuid.h (PR #97785)
https://github.com/boomanaiden154 created https://github.com/llvm/llvm-project/pull/97785 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. This patch diverges from the gcc behavior slightly bynot marking __cpuidex as static. If __cpuidex is marked as static, then this differs from the signature used by MSVC (or at least what clang uses for MSVC), which can cause include ordering issues if intrin.h (which contains a declaration for __cpuidex) occurs before cpuid.h is included. This is another attempt to land https://reviews.llvm.org/D158348. >From 38325cbf03e5013056dfc1b7939ec7c9738f9fe2 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Sat, 19 Aug 2023 13:37:21 -0700 Subject: [PATCH] [clang][X86] Add __cpuidex function to cpuid.h 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. This patch diverges from the gcc behavior slightly bynot marking __cpuidex as static. If __cpuidex is marked as static, then this differs from the signature used by MSVC (or at least what clang uses for MSVC), which can cause include ordering issues if intrin.h (which contains a declaration for __cpuidex) occurs before cpuid.h is included. --- clang/lib/Headers/cpuid.h | 10 ++ clang/test/Headers/__cpuidex_conflict.c | 22 ++ clang/test/Headers/cpuid.c | 5 + 3 files changed, 37 insertions(+) create mode 100644 clang/test/Headers/__cpuidex_conflict.c diff --git a/clang/lib/Headers/cpuid.h b/clang/lib/Headers/cpuid.h index bb7692efb78ffe..cd55410cda8b7c 100644 --- a/clang/lib/Headers/cpuid.h +++ b/clang/lib/Headers/cpuid.h @@ -339,4 +339,14 @@ static __inline int __get_cpuid_count (unsigned int __leaf, 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 */ diff --git a/clang/test/Headers/__cpuidex_conflict.c b/clang/test/Headers/__cpuidex_conflict.c new file mode 100644 index 00..8687a6aa2f897a --- /dev/null +++ b/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); +} + diff --git a/clang/test/Headers/cpuid.c b/clang/test/Headers/cpuid.c index 7e485495c10665..6ed12eca7a61d4 100644 --- a/clang/test/Headers/cpuid.c +++ b/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,~{