diff --git a/clang/lib/Headers/cpuid.h b/clang/lib/Headers/cpuid.h --- a/clang/lib/Headers/cpuid.h +++ b/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 */ diff --git a/clang/test/Headers/__cpuidex_conflict.c b/clang/test/Headers/__cpuidex_conflict.c new file mode 100644 --- /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 --- 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); }