Fix AMX tests failing with SIGILL on newer Linux kernels (#3802)

* Fix #3782: Fix AMX tests failing with SIGILL on newer Linux kernels

On Linux, applications must explicitly request permission from the kernel
via arch_prctl to use Intel AMX tile data registers (XFEATURE_XTILEDATA)
before executing any AMX instructions, otherwise the kernel kills the
process with SIGILL. Add the syscall at test harness startup and warn
on failure (e.g., when the CPU/kernel doesn't support AMX).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix #3782: Silence arch_prctl warning that corrupted print test output

The warning printed to stdout on every test process, which polluted the
stdout comparison used by print_* functional tests, causing spurious
failures. Suppress the return value silently instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix #3782: Add error message and compile flag

* Fix #3782: Remove TEST_REQUIRES_AMX from Windows builds

The AMX syscall (arch_prctl) is Linux-specific and not needed on Windows.
Windows handles AMX permissions automatically without requiring a syscall.
Removing the TEST_REQUIRES_AMX flag from Windows compilation fixes all
failing Windows test jobs.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* Fix #3782: Fix macOS bitcode generation race condition and add validation

This commit addresses intermittent test failures on macOS-15-intel by:

1. **Serialize stdlib generation** (prevents race condition):
   - Add JOB_POOLS to limit stdlib bitcode generation to 1 job at a time
   - Prevents multiple parallel jobs from reading/writing the same .bc file
   - Fixes "file too small to contain bitcode header" errors

2. **Add pipeline failure detection** (fail fast on build errors):
   - Wrap all piped commands (m4|llvm-as, clang++|llvm-as, etc.) with pipefail
   - Validate output files are non-empty with "test -s"
   - Ensures build failures are caught early, not hidden in corrupted artifacts

The race condition occurred when cmake --build -j4 caused multiple jobs to
simultaneously access stdlib bitcode files during generation. The job pool
serializes these operations while allowing other build steps to parallelize.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* Revert "Fix #3782: Fix macOS bitcode generation race condition and add validation"

This reverts commit caad76905565efa2f25114b48b336e197af6581e.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
azwolski
2026-05-04 01:11:42 +00:00
committed by GitHub
co-authored by Claude Sonnet 4.5
parent 4289e64fd5
commit 9ef79270d0
3 changed files with 47 additions and 6 deletions
+3
View File
@@ -686,6 +686,9 @@ def run_test(testname, host, target, jit_lib_path=None):
cc_cmd += ' -fPIE' cc_cmd += ' -fPIE'
if should_fail: if should_fail:
cc_cmd += " -DEXPECT_FAILURE" cc_cmd += " -DEXPECT_FAILURE"
# Enable AMX syscall for AMX-capable targets (avx512spr and later)
if target.target.startswith('avx512spr') or target.target.startswith('avx512gnr'):
cc_cmd += " -DTEST_REQUIRES_AMX"
if target.is_xe(): if target.is_xe():
exe_name = "%s.run" % os.path.basename(testname) exe_name = "%s.run" % os.path.basename(testname)
+21 -2
View File
@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2010-2024, Intel Corporation Copyright (c) 2010-2026, Intel Corporation
SPDX-License-Identifier: BSD-3-Clause SPDX-License-Identifier: BSD-3-Clause
*/ */
@@ -31,6 +31,16 @@
#if defined ISPC_IS_LINUX || defined ISPC_IS_WASM #if defined ISPC_IS_LINUX || defined ISPC_IS_WASM
#include <malloc.h> #include <malloc.h>
#endif #endif
#if defined(__linux__) && defined(__x86_64__)
#include <sys/syscall.h>
#include <unistd.h>
#ifndef ARCH_REQ_XCOMP_PERM
#define ARCH_REQ_XCOMP_PERM 0x1023
#endif
#ifndef XFEATURE_XTILEDATA
#define XFEATURE_XTILEDATA 18
#endif
#endif
#if (TEST_SIG == 7) #if (TEST_SIG == 7)
#define varying_f_sz f_sz #define varying_f_sz f_sz
@@ -53,7 +63,7 @@
#else #else
// __vectorcall calling convention is off by default. // __vectorcall calling convention is off by default.
#define CALLINGCONV //__vectorcall #define CALLINGCONV //__vectorcall
#endif // VECTORCALL_CONV #endif // VECTORCALL_CONV
#else #else
#define CALLINGCONV #define CALLINGCONV
#endif // ISPC_IS_WINDOWS64 #endif // ISPC_IS_WINDOWS64
@@ -123,6 +133,15 @@ void *ISPCAlloc(void **handle, int64_t size, int32_t alignment) {
#endif #endif
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
#if defined(__linux__) && defined(__x86_64__) && defined(TEST_REQUIRES_AMX)
// Request permission to use AMX tile data
long result = syscall(SYS_arch_prctl, ARCH_REQ_XCOMP_PERM, XFEATURE_XTILEDATA);
if (result != 0) {
fprintf(stderr, "Error: Failed to enable AMX support (syscall returned %ld). "
"AMX instructions require kernel permission on Linux 5.16+.\n", result);
return 1;
}
#endif
int w = width(); int w = width();
assert(w <= 64); assert(w <= 64);
+23 -4
View File
@@ -1,5 +1,5 @@
/* /*
Copyright (c) 2025, Intel Corporation Copyright (c) 2025-2026, Intel Corporation
SPDX-License-Identifier: BSD-3-Clause SPDX-License-Identifier: BSD-3-Clause
*/ */
@@ -35,6 +35,16 @@
#if defined ISPC_IS_LINUX || defined ISPC_IS_WASM #if defined ISPC_IS_LINUX || defined ISPC_IS_WASM
#include <malloc.h> #include <malloc.h>
#endif #endif
#if defined(__linux__) && defined(__x86_64__)
#include <sys/syscall.h>
#include <unistd.h>
#ifndef ARCH_REQ_XCOMP_PERM
#define ARCH_REQ_XCOMP_PERM 0x1023
#endif
#ifndef XFEATURE_XTILEDATA
#define XFEATURE_XTILEDATA 18
#endif
#endif
#include "ispc/ispc.h" #include "ispc/ispc.h"
@@ -129,6 +139,15 @@ bool createTemporaryISPCFile(const std::string &filename, const std::string &con
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
#if defined(__linux__) && defined(__x86_64__) && defined(TEST_REQUIRES_AMX)
// Request permission to use AMX tile data
long result = syscall(SYS_arch_prctl, ARCH_REQ_XCOMP_PERM, XFEATURE_XTILEDATA);
if (result != 0) {
fprintf(stderr, "Error: Failed to enable AMX support (syscall returned %ld). "
"AMX instructions require kernel permission on Linux 5.16+.\n", result);
return 1;
}
#endif
if (argc < 2) { if (argc < 2) {
printf("Usage: %s <ispc_source_file> [target]\n", argv[0]); printf("Usage: %s <ispc_source_file> [target]\n", argv[0]);
return 1; return 1;
@@ -174,9 +193,9 @@ int main(int argc, char *argv[]) {
} }
// Set the runtime functions that JIT will use // Set the runtime functions that JIT will use
if (!engine->SetJitRuntimeFunction("ISPCLaunch", (void*)ISPCLaunch) || if (!engine->SetJitRuntimeFunction("ISPCLaunch", (void *)ISPCLaunch) ||
!engine->SetJitRuntimeFunction("ISPCSync", (void*)ISPCSync) || !engine->SetJitRuntimeFunction("ISPCSync", (void *)ISPCSync) ||
!engine->SetJitRuntimeFunction("ISPCAlloc", (void*)ISPCAlloc)) { !engine->SetJitRuntimeFunction("ISPCAlloc", (void *)ISPCAlloc)) {
printf("Failed to set JIT runtime functions\n"); printf("Failed to set JIT runtime functions\n");
ispc::Shutdown(); ispc::Shutdown();
return 1; return 1;