[all-commits] [llvm/llvm-project] 1b6c36: [OpenMPOpt] Ask the runtime how many of a block's ...

Larry Meadows via All-commits all-commits at lists.llvm.org
Tue Sep 8 13:56:35 PDT 2026


  Branch: refs/heads/users/lfmeadow/openmpopt-gate
  Home:   https://github.com/llvm/llvm-project
  Commit: 1b6c365cc88668c5c2f8882cfd7af15d8f531b8b
      https://github.com/llvm/llvm-project/commit/1b6c365cc88668c5c2f8882cfd7af15d8f531b8b
  Author: Larry Meadows <Lawrence.Meadows at amd.com>
  Date:   2026-09-08 (Tue, 08 Sep 2026)

  Changed paths:
    M llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
    M llvm/lib/Transforms/IPO/OpenMPOpt.cpp
    M llvm/test/Transforms/OpenMP/callback_parallel_regions.ll
    M llvm/test/Transforms/OpenMP/custom_state_machines.ll
    M llvm/test/Transforms/OpenMP/spmdization.ll
    M llvm/test/Transforms/OpenMP/spmdization_guarding.ll
    M llvm/test/Transforms/OpenMP/spmdization_indirect.ll
    M llvm/test/Transforms/OpenMP/spmdization_no_guarding_two_reaching_kernels.ll
    M openmp/device/include/Interface.h
    M openmp/device/src/Mapping.cpp

  Log Message:
  -----------
  [OpenMPOpt] Ask the runtime how many of a block's threads can be workers

The custom state machine gates a thread on InitCB < BlockHwSize - WarpSize,
reconstructing the number of worker threads from the block size on the
assumption that the main thread occupies a whole warp above them. The DeviceRTL
already computes that number, in mapping::getMaxTeamThreads(), and its own
generic state machine gates on it in shouldEnterStateMachine(). Export it as
__kmpc_get_max_team_threads(IsSPMD) and call that instead, so the compiler's
state machine and the runtime's agree by construction rather than by arithmetic
that has to be kept in step with the launch geometry.

The entry point is handed the mode rather than reading it back from
mapping::isSPMDMode(), for the same reason shouldEnterStateMachine() takes it as
a parameter: IsSPMDMode lives in shared memory and only the initial thread
writes it, and in generic mode __kmpc_target_init() returns to the workers
without a barrier in between, so that write is not yet theirs to read at this
point. The compiler passes a constant, a custom state machine being built only
for a generic-mode kernel.

This is NFC here: getMaxTeamThreads() in generic mode is BlockSize - WarpSize,
the same three instructions folded into one call. It is not NFC for a toolchain
whose launch geometry differs. In ROCm, CGOpenMPRuntimeGPU starts a single extra
thread rather than a warp -- "Only one additional thread is started, not an
entire warp" -- so thread_limit(1024) on a 64-lane target launches 961 threads
and the runtime reports 960 workers, while the state machine's own arithmetic
says 961 - 64 = 897. The threads in between are in neither group: the state
machine returns immediately for them, and the parallel region still hands them
iterations. Asking the runtime removes the assumption rather than adding a
second one.

A device runtime that predates the new entry point is handled by the existing
runtimeFnsAvailable() check, which skips the rewrite rather than emitting a call
to a function that is not there.

The two calls this replaces, __kmpc_get_hardware_num_threads_in_block and
__kmpc_get_warp_size, keep their other uses in the pass, including the constant
folding of the former.



To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications


More information about the All-commits mailing list