[Openmp-commits] [openmp] 63a614c - [Clang][OpenMP] Mixed signed/unsigned trip counts fix (#226462)
via Openmp-commits
openmp-commits at lists.llvm.org
Wed Oct 7 05:30:50 PDT 2026
Author: Amit Tiwari
Date: 2026-10-07T12:30:40Z
New Revision: 63a614cadacc204e353e6c7d2c60f8fa38a4cb62
URL: https://github.com/llvm/llvm-project/commit/63a614cadacc204e353e6c7d2c60f8fa38a4cb62
DIFF: https://github.com/llvm/llvm-project/commit/63a614cadacc204e353e6c7d2c60f8fa38a4cb62.diff
LOG: [Clang][OpenMP] Mixed signed/unsigned trip counts fix (#226462)
Build that 1 already in the loop-index type (same pattern as the
existing 0).
Fixes #225756
Added:
openmp/runtime/test/transform/flatten/mixed-sign.c
Modified:
clang/lib/Sema/SemaOpenMP.cpp
clang/test/OpenMP/flatten_codegen.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index d0cf844acf6db..a3be416d2da24 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -17469,26 +17469,21 @@ SemaOpenMP::ActOnOpenMPFlattenDirective(ArrayRef<OMPClause *> Clauses,
/*AllowExplicit=*/true));
};
- // Divisors in index recovery use max(1, N) so a zero trip count does not
- // warn.
+ // Divisors in index recovery use (N == 0 ? 1 : N) so a zero trip count does
+ // not warn.
auto MakeDivisorInIVTy = [&](unsigned I) -> Expr * {
Expr *N = MakeNumIterationsInIVTy(I);
Expr *NCmp = MakeNumIterationsInIVTy(I);
- auto MakeOne = [&]() -> ExprResult {
- return SemaRef.PerformImplicitConversion(
- SemaRef.ActOnIntegerConstant(CondLoc, 1).get(), IVTy,
- AssignmentAction::Converting, /*AllowExplicit=*/true);
+ auto MakeCst = [&](uint64_t V) -> Expr * {
+ return IntegerLiteral::Create(Context, llvm::APInt(IVWidth, V), IVTy,
+ CondLoc);
};
- ExprResult OneCmp = MakeOne();
- ExprResult OneVal = MakeOne();
- if (!OneCmp.isUsable() || !OneVal.isUsable())
- return N;
- ExprResult TooSmall =
- SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, NCmp, OneCmp.get());
- if (!TooSmall.isUsable())
+ ExprResult IsZero =
+ SemaRef.BuildBinOp(CurScope, CondLoc, BO_EQ, NCmp, MakeCst(0));
+ if (!IsZero.isUsable())
return N;
return AssertSuccess(SemaRef.ActOnConditionalOp(
- CondLoc, CondLoc, TooSmall.get(), OneVal.get(), N));
+ CondLoc, CondLoc, IsZero.get(), MakeCst(1), N));
};
// \code{.cpp}
diff --git a/clang/test/OpenMP/flatten_codegen.cpp b/clang/test/OpenMP/flatten_codegen.cpp
index fe2e4350672f3..109aa16e3e079 100644
--- a/clang/test/OpenMP/flatten_codegen.cpp
+++ b/clang/test/OpenMP/flatten_codegen.cpp
@@ -6,6 +6,8 @@
#ifndef HEADER
#define HEADER
+typedef __SIZE_TYPE__ size_t;
+
extern "C" void body(int, int);
// CHECK-LABEL: define {{.*}}void @foo(
@@ -100,4 +102,16 @@ extern "C" void both_neg() {
body(i, j);
}
+// Mixed signed/unsigned trip counts: the flattened IV is unsigned, and the
+// signed inner count is converted into that type for (N == 0 ? 1 : N).
+// CHECK-LABEL: define {{.*}}void @mixed_sign(
+// CHECK: %.flatten.iv = alloca i64
+// CHECK: icmp ult i64
+extern "C" void mixed_sign(int n) {
+#pragma omp flatten depth(2)
+ for (size_t i = 0; i < (size_t)n; ++i)
+ for (int j = 0; j < n; ++j)
+ body((int)i, j);
+}
+
#endif
diff --git a/openmp/runtime/test/transform/flatten/mixed-sign.c b/openmp/runtime/test/transform/flatten/mixed-sign.c
new file mode 100644
index 0000000000000..f879274d19d12
--- /dev/null
+++ b/openmp/runtime/test/transform/flatten/mixed-sign.c
@@ -0,0 +1,40 @@
+// RUN: %libomp-compile -fopenmp-version=61 && %libomp-run \
+// RUN: | FileCheck %s --match-full-lines
+
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef __SIZE_TYPE__ size_t;
+
+static void flatten(int n) {
+#pragma omp flatten depth(2)
+ for (size_t i = 0; i < (size_t)n; ++i)
+ for (int j = 0; j < n; ++j)
+ printf("i=%zu j=%d\n", i, j);
+}
+
+int main(void) {
+ printf("n2-begin\n");
+ flatten(2);
+ printf("n2-end\n");
+
+ printf("n0-begin\n");
+ flatten(0);
+ printf("n0-end\n");
+
+ printf("nneg-begin\n");
+ flatten(-2);
+ printf("nneg-end\n");
+ return EXIT_SUCCESS;
+}
+
+// CHECK: n2-begin
+// CHECK-NEXT: i=0 j=0
+// CHECK-NEXT: i=0 j=1
+// CHECK-NEXT: i=1 j=0
+// CHECK-NEXT: i=1 j=1
+// CHECK-NEXT: n2-end
+// CHECK-NEXT: n0-begin
+// CHECK-NEXT: n0-end
+// CHECK-NEXT: nneg-begin
+// CHECK-NEXT: nneg-end
More information about the Openmp-commits
mailing list