[clang] cfa4135 - [OpenMP] Don't reserve the generic mode warp on SPIR-V (#222763)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 11 07:05:10 PDT 2026
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)));
More information about the cfe-commits
mailing list