[flang-commits] [flang] [llvm] [OMPIRBuilder] Pass work loop type in ident flags (PR #189347)
via flang-commits
flang-commits at lists.llvm.org
Mon Mar 30 03:04:04 PDT 2026
Jan =?utf-8?q?André?= Reuter <jan at zyten.de>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/189347 at github.com>
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-openmp
Author: Jan André Reuter (Thyre)
<details>
<summary>Changes</summary>
Flang uses the OMPIRBuilder to lower OpenMP constructs to LLVM IR.
When dealing with work sharing constructs, such as DO, DISTRIBUTE or SECTIONS/SECTION, OMPIRBuilder needs to construct the call to the OpenMP runtime, typically `__kmpc_for_static_init` or `__kmpc_dist_for_static_init`.
The first passed flag to these functions is the `ident_t` struct, defined in `kmp.h`. Most of the arguments are reserved for usage in Fortran and unused in `openmp`. However, the `flags` argument is used throughout the code base to identify specific constructs, such as the type of work sharing construct.
In https://github.com/llvm/llvm-project/issues/112545, it was identified that Flang does not provide the correct `ident_t` flags when calling into e.g. `__kmpc_for_static_init`, causing the following runtime warning to appear when the OpenMP Tools Interface is used:
```
OMP: Warning #<!-- -->189: OMPT: Cannot determine workshare type; using the default (loop) instead. This issue is fixed in an up-to-date compiler.
```
This PR adds a test, verifying that the work sharing constructs provide the correct flags to the runtime call. The IR check for SECTIONS/SECTION maps against `KMP_IDENT_WORK_LOOP`, as the OMPIRBuilder converts the SECTIONS construct into a DO loop with a switch-case for every SECTION clause.
In addition, `OMPIRBuilder` is modified, so that the work loop type is passed via `ident_t.flags` to the respective `__kmpc_for_static_init`/`__kmpc_dist_for_static_init` calls, letting the test pass and the `libomp` warning disappear.
Wherever possible, provide the mapping based on the passed `LoopType`. If not available, I implemented the decision based on the `DistScheduleSchedType`, or in case of `applyDynamicWorkshareLoop`, hard-coded this to `OMP_IDENT_FLAG_WORK_LOOP`.
---
As this is the first time dealing with `OMPIRBuilder`, I'm not sure if I missed anything while implementing these changes.
If there's anything that can be improved here, e.g. with the ident flag mapping, I'm very grateful for any feedback. I tried to implement this with the best of my understanding based on taking a look at the existing code and tests.
For example, I was not sure if adding a test to `flang/test/Integration/OpenMP/` is the correct approach here, or if I rather should try to modify `unittests/Frontend/OpenMPIRBuilderTest.cpp`. In the end, the former looked to me more straight-forward.
---
Fixes https://github.com/llvm/llvm-project/issues/112545
---
Full diff: https://github.com/llvm/llvm-project/pull/189347.diff
3 Files Affected:
- (added) flang/test/Integration/OpenMP/workshare-ident-flag.f90 (+73)
- (modified) llvm/include/llvm/Frontend/OpenMP/OMPKinds.def (+3)
- (modified) llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp (+39-4)
``````````diff
diff --git a/flang/test/Integration/OpenMP/workshare-ident-flag.f90 b/flang/test/Integration/OpenMP/workshare-ident-flag.f90
new file mode 100644
index 0000000000000..3612ba9cf7c63
--- /dev/null
+++ b/flang/test/Integration/OpenMP/workshare-ident-flag.f90
@@ -0,0 +1,73 @@
+!===----------------------------------------------------------------------===!
+! This directory can be used to add Integration tests involving multiple
+! stages of the compiler (for eg. from Fortran to LLVM IR). It should not
+! contain executable tests. We should only add tests here sparingly and only
+! if there is no other way to test. Repeat this message in each test that is
+! added to this directory and sub-directories.
+!===----------------------------------------------------------------------===!
+
+! RUN: %flang_fc1 -fopenmp -emit-llvm %s -o - | FileCheck %s
+
+! Regression test for https://github.com/llvm/llvm-project/issues/112545
+! Test if OMPIRBuilder passes the correct ident_f->flags for worksharing constructs. Intended:
+! DO: ident_t->flags == 0x200 (KMP_IDENT_WORK_LOOP) | 0x002 (KMP_IDENT_KMPC)
+! SECTIONS/SECTION: ident_t->flags == 0x200 (KMP_IDENT_WORK_LOOP) | 0x002 (KMP_IDENT_KMPC)
+! DISTRIBUTE: ident_t->flags == 0x800 (KMP_IDENT_WORK_DISTRIBUTE) | 0x002 (KMP_IDENT_KMPC)
+! DISTRIBUTE DO:
+! ident_t->flags == 0x800 (KMP_IDENT_WORK_DISTRIBUTE) | 0x200 (KMPC_IDENT_WORK_LOOP | 0x002 (KMP_IDENT_KMPC)
+
+subroutine workshare_do_ident_flag()
+ integer :: i
+
+ !$OMP PARALLEL
+ !$OMP DO
+ do i = 1, 10
+ end do
+ !$OMP END DO
+ !$OMP END PARALLEL
+end subroutine workshare_do_ident_flag
+
+subroutine workshare_sections_ident_flag()
+ !$OMP PARALLEL
+ !$OMP SECTIONS
+ !$OMP SECTION
+ block
+ end block
+ !$OMP END SECTIONS
+ !$OMP END PARALLEL
+end subroutine workshare_sections_ident_flag
+
+subroutine workshare_distribute_ident_flag()
+ integer :: i
+
+ !$OMP TEAMS
+ !$OMP DISTRIBUTE
+ do i = 1, 10
+ end do
+ !$OMP END DISTRIBUTE
+ !$OMP END TEAMS
+end subroutine workshare_distribute_ident_flag
+
+subroutine workshare_distribute_do_ident_flag()
+ integer :: i
+
+ !$OMP TEAMS
+ !$OMP DISTRIBUTE PARALLEL DO
+ do i = 1, 10
+ end do
+ !$OMP END DISTRIBUTE PARALLEL DO
+ !$OMP END TEAMS
+end subroutine workshare_distribute_do_ident_flag
+
+! CHECK: @[[IDENT_DO:[0-9]+]] = private unnamed_addr constant %struct.ident_t { i32 {{[0-9]+}}, i32 514, i32 {{[0-9]+}}, i32 {{[0-9]+}}, ptr @0 }, align 8
+! CHECK: @[[IDENT_DISTRIBUTE:[0-9]+]] = private unnamed_addr constant %struct.ident_t { i32 {{[0-9]+}}, i32 2050, i32 {{[0-9]+}}, i32 {{[0-9]+}}, ptr @0 }, align 8
+! CHECK: @[[IDENT_DISTRIBUTE_DO:[0-9]+]] = private unnamed_addr constant %struct.ident_t { i32 {{[0-9]+}}, i32 2562, i32 {{[0-9]+}}, i32 {{[0-9]+}}, ptr @0 }, align 8
+
+! Test workshare_do_ident_flag
+! CHECK: call void @__kmpc_for_static_init_{{.*}}(ptr @[[IDENT_DO]], {{.*}})
+! Test workshare_sections_ident_flag
+! CHECK: call void @__kmpc_for_static_init_{{.*}}(ptr @[[IDENT_DO]], {{.*}})
+! Test workshare_distribute_ident_flag
+! CHECK: call void @__kmpc_for_static_init_{{.*}}(ptr @[[IDENT_DISTRIBUTE]], {{.*}})
+! Test workshare_distribute_do_ident_flag
+! CHECK: call void @__kmpc_dist_for_static_init_{{.*}}(ptr @[[IDENT_DISTRIBUTE_DO]], {{.*}})
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
index 5fe7ee8997243..e0e1b832e51c9 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
+++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
@@ -1135,6 +1135,9 @@ __OMP_IDENT_FLAG(BARRIER_IMPL_FOR, 0x0040)
__OMP_IDENT_FLAG(BARRIER_IMPL_SECTIONS, 0x00C0)
__OMP_IDENT_FLAG(BARRIER_IMPL_SINGLE, 0x0140)
__OMP_IDENT_FLAG(BARRIER_IMPL_WORKSHARE, 0x01C0)
+__OMP_IDENT_FLAG(WORK_LOOP, 0x200)
+__OMP_IDENT_FLAG(WORK_SECTIONS, 0x400)
+__OMP_IDENT_FLAG(WORK_DISTRIBUTE, 0x800)
#undef __OMP_IDENT_FLAG
#undef OMP_IDENT_FLAG
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 2bd054501506a..b25a8b1e3194a 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -5443,7 +5443,22 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::applyStaticWorkshareLoop(
uint32_t SrcLocStrSize;
Constant *SrcLocStr = getOrCreateSrcLocStr(DL, SrcLocStrSize);
- Value *SrcLoc = getOrCreateIdent(SrcLocStr, SrcLocStrSize);
+ IdentFlag Flag;
+ switch (LoopType) {
+ case WorksharingLoopType::ForStaticLoop:
+ Flag = OMP_IDENT_FLAG_WORK_LOOP;
+ break;
+ case WorksharingLoopType::DistributeStaticLoop:
+ Flag = OMP_IDENT_FLAG_WORK_DISTRIBUTE;
+ break;
+ case WorksharingLoopType::DistributeForStaticLoop:
+ Flag = OMP_IDENT_FLAG_WORK_DISTRIBUTE | OMP_IDENT_FLAG_WORK_LOOP;
+ break;
+ default:
+ Flag = IdentFlag(0);
+ break;
+ }
+ Value *SrcLoc = getOrCreateIdent(SrcLocStr, SrcLocStrSize, Flag);
// Declare useful OpenMP runtime functions.
Value *IV = CLI->getIndVar();
@@ -5666,7 +5681,11 @@ OpenMPIRBuilder::applyStaticChunkedWorkshareLoop(
// value it produced.
uint32_t SrcLocStrSize;
Constant *SrcLocStr = getOrCreateSrcLocStr(DL, SrcLocStrSize);
- Value *SrcLoc = getOrCreateIdent(SrcLocStr, SrcLocStrSize);
+ IdentFlag Flag = OMP_IDENT_FLAG_WORK_LOOP;
+ if (DistScheduleSchedType != OMPScheduleType::None) {
+ Flag |= OMP_IDENT_FLAG_WORK_DISTRIBUTE;
+ }
+ Value *SrcLoc = getOrCreateIdent(SrcLocStr, SrcLocStrSize, Flag);
Value *ThreadNum = getOrCreateThreadID(SrcLoc);
auto BuildInitCall = [StaticInit, SrcLoc, ThreadNum, PLastIter, PLowerBound,
PUpperBound, PStride, One,
@@ -5923,7 +5942,22 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::applyWorkshareLoopTarget(
WorksharingLoopType LoopType, bool NoLoop) {
uint32_t SrcLocStrSize;
Constant *SrcLocStr = getOrCreateSrcLocStr(DL, SrcLocStrSize);
- Value *Ident = getOrCreateIdent(SrcLocStr, SrcLocStrSize);
+ IdentFlag Flag;
+ switch (LoopType) {
+ case WorksharingLoopType::ForStaticLoop:
+ Flag = OMP_IDENT_FLAG_WORK_LOOP;
+ break;
+ case WorksharingLoopType::DistributeStaticLoop:
+ Flag = OMP_IDENT_FLAG_WORK_DISTRIBUTE;
+ break;
+ case WorksharingLoopType::DistributeForStaticLoop:
+ Flag = OMP_IDENT_FLAG_WORK_DISTRIBUTE | OMP_IDENT_FLAG_WORK_LOOP;
+ break;
+ default:
+ Flag = IdentFlag(0);
+ break;
+ }
+ Value *Ident = getOrCreateIdent(SrcLocStr, SrcLocStrSize, Flag);
OutlineInfo OI;
OI.OuterAllocaBB = CLI->getPreheader();
@@ -6145,7 +6179,8 @@ OpenMPIRBuilder::applyDynamicWorkshareLoop(DebugLoc DL, CanonicalLoopInfo *CLI,
uint32_t SrcLocStrSize;
Constant *SrcLocStr = getOrCreateSrcLocStr(DL, SrcLocStrSize);
- Value *SrcLoc = getOrCreateIdent(SrcLocStr, SrcLocStrSize);
+ Value *SrcLoc =
+ getOrCreateIdent(SrcLocStr, SrcLocStrSize, OMP_IDENT_FLAG_WORK_LOOP);
// Declare useful OpenMP runtime functions.
Value *IV = CLI->getIndVar();
``````````
</details>
https://github.com/llvm/llvm-project/pull/189347
More information about the flang-commits
mailing list