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

Reply via email to