[clang] [llvm] [Flang][OpenMP] Fix OpenMP static scheduling when trip count is zero (PR #170863)
Michael Klemm via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 5 07:52:24 PST 2025
https://github.com/mjklemm updated https://github.com/llvm/llvm-project/pull/170863
>From 5bd0974817c7e6f2f1964acf1d5e1b372a00535c Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael at dontknow.de>
Date: Fri, 5 Dec 2025 14:27:57 +0100
Subject: [PATCH 1/2] [Flang][OpenMP] Fix OpenMP static scheduling when trip
count is zero
Code-gen produced incorrect code for cases when the trip count an
associated DO loop was zero. The generated code evaluated the trip
count of the loop and substracted 1 from it. When this was passed to
__kmpc_for_static_init_4u, the value was interpreted as unsigned, which
made the upper bound of the worksharing loop 2^32-1 and caused a
division by zero in the calculation of the loop bounds for the threads.
---
llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index fff9a815e5368..694b98225f8c5 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -4829,7 +4829,10 @@ OpenMPIRBuilder::applyStaticChunkedWorkshareLoop(DebugLoc DL,
I32Type, static_cast<int>(OMPScheduleType::UnorderedStaticChunked));
Builder.CreateStore(Zero, PLowerBound);
Value *OrigUpperBound = Builder.CreateSub(CastedTripCount, One);
- Builder.CreateStore(OrigUpperBound, PUpperBound);
+ Value *IsTripCountZero = Builder.CreateICmpEQ(CastedTripCount, Zero);
+ Value *UpperBound =
+ Builder.CreateSelect(IsTripCountZero, Zero, OrigUpperBound);
+ Builder.CreateStore(UpperBound, PUpperBound);
Builder.CreateStore(One, PStride);
// Call the "init" function and update the trip count of the loop with the
>From b3bcd07d31cef4a49763d8f5d6fa435e073ceb79 Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael at dontknow.de>
Date: Fri, 5 Dec 2025 16:52:13 +0100
Subject: [PATCH 2/2] Update test case
---
clang/test/OpenMP/irbuilder_for_unsigned_static_chunked.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/clang/test/OpenMP/irbuilder_for_unsigned_static_chunked.c b/clang/test/OpenMP/irbuilder_for_unsigned_static_chunked.c
index b937568ca9f11..dfa5e8a6e0943 100644
--- a/clang/test/OpenMP/irbuilder_for_unsigned_static_chunked.c
+++ b/clang/test/OpenMP/irbuilder_for_unsigned_static_chunked.c
@@ -50,7 +50,9 @@ extern "C" void workshareloop_unsigned_static_chunked(float *a, float *b, float
// CHECK: omp_loop.preheader:
// CHECK-NEXT: store i32 0, ptr [[P_LOWERBOUND]], align 4
// CHECK-NEXT: [[TMP3:%.*]] = sub i32 [[DOTCOUNT]], 1
-// CHECK-NEXT: store i32 [[TMP3]], ptr [[P_UPPERBOUND]], align 4
+// CHECK-NEXT: [[COUNTCOND:%.*]] = icmp eq i32 [[DOTCOUNT]], 0
+// CHECK-NEXT: [[UPPERSEL:%.*]] = select i1 [[COUNTCOND]], i32 0, i32 [[TMP3]]
+// CHECK-NEXT: store i32 [[UPPERSEL]], ptr [[P_UPPERBOUND]], align 4
// CHECK-NEXT: store i32 1, ptr [[P_STRIDE]], align 4
// CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]])
// CHECK-NEXT: call void @__kmpc_for_static_init_4u(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM]], i32 33, ptr [[P_LASTITER]], ptr [[P_LOWERBOUND]], ptr [[P_UPPERBOUND]], ptr [[P_STRIDE]], i32 1, i32 5)
More information about the llvm-commits
mailing list