Skip to content

[win][arm64ec] Fixes to unblock building LLVM and Clang as Arm64EC #150068

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions clang/tools/clang-repl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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})

Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Support/BLAKE3/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 8 additions & 5 deletions llvm/lib/TargetParser/Host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -2147,7 +2149,8 @@ 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;

Expand Down
16 changes: 9 additions & 7 deletions llvm/tools/llvm-exegesis/lib/X86/Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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__)
Expand All @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions third-party/benchmark/src/cycleclock.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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__)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is third-party code; can we submit this upstream?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// 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
Expand Down