[llvm] [OpenMP][offload] Add enhanced cross-team reduction test (PR #195940)
Robert Imschweiler via llvm-commits
llvm-commits at lists.llvm.org
Fri May 8 00:32:59 PDT 2026
ro-i wrote:
Yup. If we compile the test with save-temps and then look at the definition and usages of `@__kmpc_nvptx_teams_reduce_nowait_v2` in `a.out.amdgcn.gfx90a.img.0.5.precodegen.ll`:
teams_reduce is called like this:
`call fastcc i32 @__kmpc_nvptx_teams_reduce_nowait_v2(ptr %45, ptr %.omp.reduction.red_list.ascast.i, ptr nonnull @_omp_reduction_shuffle_and_reduce_func.5, ptr nonnull @_omp_reduction_inter_warp_copy_func.6, ptr nonnull @_omp_reduction_list_to_global_copy_func.7, ptr nonnull @_omp_reduction_list_to_global_reduce_func.8, ptr nonnull @_omp_reduction_global_to_list_copy_func.9, ptr nonnull @_omp_reduction_global_to_list_reduce_func.10) #24`
or like this:
`call fastcc i32 @__kmpc_nvptx_teams_reduce_nowait_v2(ptr %45, ptr %.omp.reduction.red_list.ascast.i, ptr nonnull @_omp_reduction_shuffle_and_reduce_func.13, ptr nonnull @_omp_reduction_inter_warp_copy_func.14, ptr nonnull @_omp_reduction_list_to_global_copy_func.15, ptr nonnull @_omp_reduction_list_to_global_reduce_func.16, ptr nonnull @_omp_reduction_global_to_list_copy_func.17, ptr nonnull @_omp_reduction_global_to_list_reduce_func.18) #24`
or this:
`call fastcc i32 @__kmpc_nvptx_teams_reduce_nowait_v2(ptr %49, ptr %.omp.reduction.red_list.ascast.i, ptr nonnull @_omp_reduction_shuffle_and_reduce_func.21, ptr nonnull @_omp_reduction_inter_warp_copy_func.22, ptr nonnull @_omp_reduction_list_to_global_copy_func.23, ptr nonnull @_omp_reduction_list_to_global_reduce_func.24, ptr nonnull @_omp_reduction_global_to_list_copy_func.25, ptr nonnull @_omp_reduction_global_to_list_reduce_func.26) #24`
Note that we have different function pointers every time.
Then, looking at the definition of teams_reduce, we see stuff like this. For example, for the `@_omp_reduction_list_to_global_copy_func.X` variants:
```llvm
49: ; preds = %46
%50 = icmp eq ptr %4, @_omp_reduction_list_to_global_copy_func
br i1 %50, label %51, label %57
51: ; preds = %49
%52 = addrspacecast ptr %1 to ptr addrspace(5)
%53 = load ptr, ptr addrspace(5) %52, align 8
%54 = zext nneg i32 %47 to i64
%55 = getelementptr inbounds nuw [8 x i8], ptr %0, i64 %54
%56 = load double, ptr %53, align 8
store double %56, ptr %55, align 8
br label %429
57: ; preds = %49
%58 = icmp eq ptr %4, @_omp_reduction_list_to_global_copy_func.7
br i1 %58, label %59, label %65
59: ; preds = %57
%60 = addrspacecast ptr %1 to ptr addrspace(5)
%61 = load ptr, ptr addrspace(5) %60, align 8
%62 = zext nneg i32 %47 to i64
%63 = getelementptr inbounds nuw [8 x i8], ptr %0, i64 %62
%64 = load double, ptr %61, align 8
store double %64, ptr %63, align 8
br label %429
65: ; preds = %57
%66 = icmp eq ptr %4, @_omp_reduction_list_to_global_copy_func.15
br i1 %66, label %67, label %73
... <a lot more comparisons to @_omp_reduction_list_to_global_copy_func.X are following> ...
```
Or, a different pattern, this time for the `@_omp_reduction_global_to_list_reduce_func.X` variants, where some sort of hoisting is used:
```llvm
.preheader: ; preds = %623
%626 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func
%627 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.10
%628 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.18
%629 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.26
%630 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.34
%631 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.45
%632 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.54
%633 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.62
%634 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.70
%635 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.78
%636 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.86
%637 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.97
%638 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.106
%639 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.114
%640 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.122
%641 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.130
%642 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.138
%643 = icmp eq ptr %7, @_omp_reduction_global_to_list_reduce_func.149
%644 = addrspacecast ptr %1 to ptr addrspace(5)
%645 = getelementptr inbounds nuw i8, ptr %1, i64 8
%646 = addrspacecast ptr %645 to ptr addrspace(5)
br label %648
```
That's what I meant by "dispatch chains". And they grow by the number of reductions per translation unit. To me, this looks like the issue is that the helper functions *are* inlined, but the parent functions like teams_reduce not. Because if they were (see the other PR), then there would be a 1:1 mapping between the parent functions and the helper functions and thus no dispatch chains.
https://github.com/llvm/llvm-project/pull/195940
More information about the llvm-commits
mailing list