https://github.com/dpaoliello updated https://github.com/llvm/llvm-project/pull/150068
>From 7c573fb412a0701e7e5573d989c42ff14d906129 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello <dan...@microsoft.com> Date: Tue, 22 Jul 2025 10:17:02 -0700 Subject: [PATCH] Fixes to unblock building LLVM and Clang as Arm64EC --- clang/tools/clang-repl/CMakeLists.txt | 15 +++++++++------ llvm/lib/Support/BLAKE3/CMakeLists.txt | 3 ++- llvm/lib/TargetParser/Host.cpp | 15 +++++++++------ llvm/tools/llvm-exegesis/lib/X86/Target.cpp | 16 +++++++++------- third-party/benchmark/src/cycleclock.h | 4 ++-- 5 files changed, 31 insertions(+), 22 deletions(-) diff --git a/clang/tools/clang-repl/CMakeLists.txt b/clang/tools/clang-repl/CMakeLists.txt index 68d86dd98cac3..c3d14ceb79792 100644 --- a/clang/tools/clang-repl/CMakeLists.txt +++ b/clang/tools/clang-repl/CMakeLists.txt @@ -19,14 +19,14 @@ if(MSVC) set_target_properties(clang-repl PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS 1) # RTTI/C++ symbols - set(clang_repl_exports ${clang_repl_exports} ??_7type_info@@6B@ - ?__type_info_root_node@@3U__type_info_node@@A - ?nothrow@std@@3Unothrow_t@1@B + set(clang_repl_exports ${clang_repl_exports} ??_7type_info@@6B@,DATA + ?__type_info_root_node@@3U__type_info_node@@A,DATA + ?nothrow@std@@3Unothrow_t@1@B,DATA ) # Compiler added symbols for static variables. NOT for VStudio < 2015 - set(clang_repl_exports ${clang_repl_exports} _Init_thread_abort _Init_thread_epoch - _Init_thread_footer _Init_thread_header _tls_index + set(clang_repl_exports ${clang_repl_exports} _Init_thread_abort _Init_thread_epoch,DATA + _Init_thread_footer _Init_thread_header _tls_index,DATA ) if(CMAKE_SIZEOF_VOID_P EQUAL 8) @@ -50,7 +50,10 @@ if(MSVC) endif() # List to '/EXPORT:sym0 /EXPORT:sym1 /EXPORT:sym2 ...' - list(TRANSFORM clang_repl_exports PREPEND "LINKER:/EXPORT:") + # The 'SHELL' prefix tells CMake to use a space instead of comma as the + # separator between the driver and linker options, which we need since MSVC's + # linker uses `,DATA` as a suffix to indicate that data is being exported. + list(TRANSFORM clang_repl_exports PREPEND "LINKER:SHELL:/EXPORT:") set_property(TARGET clang-repl APPEND PROPERTY LINK_OPTIONS ${clang_repl_exports}) diff --git a/llvm/lib/Support/BLAKE3/CMakeLists.txt b/llvm/lib/Support/BLAKE3/CMakeLists.txt index eae2b0280e5d3..90311ae247219 100644 --- a/llvm/lib/Support/BLAKE3/CMakeLists.txt +++ b/llvm/lib/Support/BLAKE3/CMakeLists.txt @@ -26,7 +26,8 @@ endmacro() if (CAN_USE_ASSEMBLER) if (MSVC) check_symbol_exists(_M_X64 "" IS_X64) - if (IS_X64) + check_symbol_exists(_M_ARM64EC "" IS_ARM64EC) + if (IS_X64 AND NOT IS_ARM64EC) enable_language(ASM_MASM) set(LLVM_BLAKE3_ASM_FILES blake3_sse2_x86-64_windows_msvc.asm diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index 78bd5b4b5bd25..9c532340b54cf 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -587,8 +587,9 @@ StringRef sys::detail::getHostCPUNameForBPF() { #endif } -#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \ - defined(_M_X64) +#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \ + defined(_M_X64)) && \ + !defined(_M_ARM64EC) /// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in /// the specified arguments. If we can't run cpuid on the host, return true. @@ -1853,8 +1854,9 @@ VendorSignatures getVendorSignature(unsigned *MaxLeaf) { } // namespace llvm #endif -#if defined(__i386__) || defined(_M_IX86) || \ - defined(__x86_64__) || defined(_M_X64) +#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \ + defined(_M_X64)) && \ + !defined(_M_ARM64EC) StringMap<bool> sys::getHostCPUFeatures() { unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; unsigned MaxLevel; @@ -2067,7 +2069,8 @@ StringMap<bool> sys::getHostCPUFeatures() { return Features; } -#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__)) +#elif defined(__linux__) && \ + (defined(__arm__) || defined(__aarch64__)) StringMap<bool> sys::getHostCPUFeatures() { StringMap<bool> Features; std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); @@ -2147,7 +2150,7 @@ StringMap<bool> sys::getHostCPUFeatures() { return Features; } -#elif defined(_WIN32) && (defined(__aarch64__) || defined(_M_ARM64)) +#elif defined(_WIN32) && (defined(__aarch64__) || defined(_M_ARM64) || defined(__arm64ec__) || defined(_M_ARM64EC)) StringMap<bool> sys::getHostCPUFeatures() { StringMap<bool> Features; diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp index 1659cfb31f117..5dae6c0a25fab 100644 --- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp @@ -30,11 +30,12 @@ #include <memory> #include <string> #include <vector> -#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) +#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && \ + !defined(_M_ARM64EC) #include <immintrin.h> #include <intrin.h> #endif -#if defined(_MSC_VER) && defined(_M_X64) +#if defined(_MSC_VER) && defined(_M_X64) && !defined(_M_ARM64EC) #include <float.h> // For _clearfp in ~X86SavedState(). #endif @@ -654,7 +655,7 @@ namespace { class X86SavedState : public ExegesisTarget::SavedState { public: X86SavedState() { -#if defined(_MSC_VER) && defined(_M_X64) +#if defined(_MSC_VER) && defined(_M_X64) && !defined(_M_ARM64EC) _fxsave64(FPState); Eflags = __readeflags(); #elif defined(__GNUC__) && defined(__x86_64__) @@ -668,7 +669,7 @@ class X86SavedState : public ExegesisTarget::SavedState { ~X86SavedState() { // Restoring the X87 state does not flush pending exceptions, make sure // these exceptions are flushed now. -#if defined(_MSC_VER) && defined(_M_X64) +#if defined(_MSC_VER) && defined(_M_X64) && !defined(_M_ARM64EC) _clearfp(); _fxrstor64(FPState); __writeeflags(Eflags); @@ -682,7 +683,7 @@ class X86SavedState : public ExegesisTarget::SavedState { } private: -#if defined(__x86_64__) || defined(_M_X64) +#if defined(__x86_64__) || defined(_M_X64) && !defined(_M_ARM64EC) alignas(16) char FPState[512]; uint64_t Eflags; #endif @@ -824,8 +825,9 @@ class ExegesisX86Target : public ExegesisTarget { // For now, only do the check if we see an Intel machine because // the counter uses some intel-specific magic and it could // be confuse and think an AMD machine actually has LBR support. -#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \ - defined(_M_X64) +#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \ + defined(_M_X64)) && \ + !defined(_M_ARM64EC) using namespace sys::detail::x86; if (getVendorSignature() == VendorSignatures::GENUINE_INTEL) diff --git a/third-party/benchmark/src/cycleclock.h b/third-party/benchmark/src/cycleclock.h index d4f1330b671db..c0dffcf4b35f6 100644 --- a/third-party/benchmark/src/cycleclock.h +++ b/third-party/benchmark/src/cycleclock.h @@ -79,7 +79,7 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() { int64_t ret; __asm__ volatile("rdtsc" : "=A"(ret)); return ret; -#elif defined(__x86_64__) || defined(__amd64__) +#elif (defined(__x86_64__) || defined(__amd64__)) && !defined(__arm64ec__) uint64_t low, high; __asm__ volatile("rdtsc" : "=a"(low), "=d"(high)); return (high << 32) | low; @@ -139,7 +139,7 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() { struct timespec ts = {0, 0}; clock_gettime(CLOCK_MONOTONIC, &ts); return static_cast<int64_t>(ts.tv_sec) * 1000000000 + ts.tv_nsec; -#elif defined(__aarch64__) +#elif defined(__aarch64__) || defined(__arm64ec__) // System timer of ARMv8 runs at a different frequency than the CPU's. // The frequency is fixed, typically in the range 1-50MHz. It can be // read at CNTFRQ special register. We assume the OS has set up _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits