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


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to