Skip to content

gh-157212: Fix _Py_ThreadId() on Windows ARM64 with MinGW - #157253

Open
christianaurichzm wants to merge 1 commit into
python:mainfrom
christianaurichzm:fix-threadid-mingw-arm64
Open

gh-157212: Fix _Py_ThreadId() on Windows ARM64 with MinGW#157253
christianaurichzm wants to merge 1 commit into
python:mainfrom
christianaurichzm:fix-threadid-mingw-arm64

Conversation

@christianaurichzm

Copy link
Copy Markdown

Fixes #157212

_Py_ThreadId() currently uses __getReg(18) for the MinGW ARM64 branch:

#elif defined(__MINGW32__) && defined(_M_ARM64)
    tid = __getReg(18);

That intrinsic is not available for MinGW ARM64. For a *-windows-gnu target, Clang's intrin.h defers to mingw-w64's header, which declares __getReg only for Itanium. GCC does not provide a corresponding builtin either.

The branch is reached by AArch64 MinGW toolchains because mingw-w64 defines _M_ARM64 when __aarch64__ is defined.

Falling through to the generic __aarch64__ implementation is not a valid alternative. The Windows ARM64 ABI reserves x18 as the platform register pointing to the Thread Environment Block (TEB). In the system tested in gh-157212, x18 also matched NtCurrentTeb() for each tested thread, while tpidr_el0 was observed as zero.

This change therefore reads the TEB address directly from x18 for MinGW
ARM64:

__asm__ ("mov %0, x18" : "=r" (tid));

The MSVC branch is unchanged.

Verification

I reproduced the original compile failure with zig cc/Clang targeting
aarch64-windows-gnu:

error: call to undeclared function '__getReg'; ISO C99 and later do not
support implicit function declarations [-Wimplicit-function-declaration]

With this change, the same target compiles successfully and at -O2 emits the expected register read:

mov     x0, x18
ret

The change is limited to the MinGW ARM64 branch.

AI tools were used to help organize and edit the wording of this PR description.

The __MINGW32__ && _M_ARM64 branch calls __getReg(18), mirroring the MSVC branch above it. The intrinsic is not available for MinGW ARM64: mingw-w64 declares __getReg only for Itanium, and GCC does not provide a corresponding builtin.

The branch is reached by AArch64 MinGW toolchains because mingw-w64 defines _M_ARM64 when __aarch64__ is defined.

Falling through to the generic __aarch64__ branch would not provide the Windows thread pointer. The Windows ARM64 ABI reserves x18 as the platform register pointing to the TEB, so read x18 directly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

_Py_ThreadId() fails to compile with clang on Windows ARM64 (MSYS2 CLANGARM64)

1 participant