Author: Larry Meadows Date: 2026-09-11T14:05:06Z New Revision: cfa4135a9d324b3c539d9f874509ba03a8b0106f
URL: https://github.com/llvm/llvm-project/commit/cfa4135a9d324b3c539d9f874509ba03a8b0106f DIFF: https://github.com/llvm/llvm-project/commit/cfa4135a9d324b3c539d9f874509ba03a8b0106f.diff LOG: [OpenMP] Don't reserve the generic mode warp on SPIR-V (#222763) #218790 widened a generic mode kernel's thread bound by a warp so that the main thread has one of its own. The bound is what lets the runtime's own warp addition through: `getEffectiveNumThreads()` adds a warp and then clamps to the bound, so before that change the addition was clamped straight back off, which is why a `thread_limit` below one wavefront ended up with no workers. Widening the bound is the fix, and it is also what makes every generic mode kernel launch a warp wider than it used to. `hasGridValue()` covers SPIR-V, so that geometry change reached Level Zero. @sarnex reports hangs and intermittent failures there and asked about a revert in https://github.com/llvm/llvm-project/pull/222097#issuecomment-5609354538. The motivating bug was on AMDGPU, so this restricts the reservation to the targets it was written for and gives SPIR-V back the launch geometry it had before. Measured on gfx90a, generic mode, threads per block for a given `thread_limit`: | `thread_limit` | launched | | --- | --- | | 1 | 65 | | 4 | 68 | | 64 | 128 | | 256 | 320 | | 1024 | 1024 (clamped) | Before #218790 each of those launched exactly `thread_limit`, because the clamp removed the runtime's warp again. SPIR-V goes back to that with this patch: `thread_limit(4)` writes a bound of 4 rather than 68, while AMDGPU keeps 68. I have not reproduced the Level Zero failures — I have no Intel device, and OpenMP offload to `spirv64-amd-amdhsa` is not a working path, so AMD hardware cannot stand in. What this patch does establish is that SPIR-V's bound returns to its pre-#218790 value, so it undoes the geometry change whether or not that is the whole story. @sarnex, could you try it on the Level Zero runner? This is a narrowing rather than a claim that SPIR-V never wants the reserved warp. Without it a SPIR-V `thread_limit` below a warp has the same no-workers problem #218790 fixed elsewhere; it is just not reachable today. If Level Zero grows the handling, this can come back. Testing: `clang/test/OpenMP` 1613 passed, `llvm/test/Transforms/{OpenMP,Attributor}` 263 passed, `LLVMFrontendTests` 1322 passed. Two tests needed updating, both of which encode SPIR-V thread bounds. Added: Modified: clang/test/OpenMP/ompx_attributes_codegen.cpp clang/test/OpenMP/target_num_teams_num_threads_attributes.cpp llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp Removed: ################################################################################ diff --git a/clang/test/OpenMP/ompx_attributes_codegen.cpp b/clang/test/OpenMP/ompx_attributes_codegen.cpp index 44c9c319f016f..efe33bff3bb9a 100644 --- a/clang/test/OpenMP/ompx_attributes_codegen.cpp +++ b/clang/test/OpenMP/ompx_attributes_codegen.cpp @@ -34,9 +34,10 @@ void func() { {} } +// SPIRV keeps the unwidened bound: the generic-mode warp is not reserved there. // SPIRV: attributes #0 -// SPIRV-SAME: "nvvm.maxntid"="84" -// SPIRV-SAME: "omp_target_thread_limit"="84" +// SPIRV-SAME: "nvvm.maxntid"="20" +// SPIRV-SAME: "omp_target_thread_limit"="20" // SPIRV: attributes #4 // SPIRV-SAME: "amdgpu-waves-per-eu"="3,7" // SPIRV-SAME: "nvvm.maxntid"="17" diff --git a/clang/test/OpenMP/target_num_teams_num_threads_attributes.cpp b/clang/test/OpenMP/target_num_teams_num_threads_attributes.cpp index d0b5db7d64146..c8d0112fb35e3 100644 --- a/clang/test/OpenMP/target_num_teams_num_threads_attributes.cpp +++ b/clang/test/OpenMP/target_num_teams_num_threads_attributes.cpp @@ -90,7 +90,9 @@ void thread_limit_at_max() { // CHECK: "omp_target_num_teams"="33" // CHECK: "omp_target_num_teams"="44" -// CHECK: "omp_target_thread_limit"="86" +// Widened by a warp for generic mode, except on SPIRV, which does not reserve +// one. +// CHECK: "omp_target_thread_limit"="{{86|22}}" // CHECK: "omp_target_thread_limit"="11" diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp index 07bd542ae571c..e7dad1829f383 100644 --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -8605,9 +8605,10 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createTargetInit( } // Generic mode runs the main thread on a warp of its own, past thread_limit. - // Reserve the widest warp any target has. + // Reserve the widest warp any target has. Not on SPIR-V, causes problems with + // Level Zero. if (MaxThreadsVal > 0 && Attrs.ExecFlags == omp::OMP_TGT_EXEC_MODE_GENERIC && - hasGridValue(T)) + hasGridValue(T) && !T.isSPIRV()) MaxThreadsVal = int32_t( std::min<int64_t>(int64_t(MaxThreadsVal) + 64, int64_t(getGridValue(T, Kernel).GV_Max_WG_Size))); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
