https://github.com/jprotze created 
https://github.com/llvm/llvm-project/pull/99347

The expectation for multiple iterators used in a single depend clause 
(`depend(iterator(i=0:5,j=0:5), in:x[i][j])`) is that the iterator space is the 
product of the iteration vectors (25 in that case). The current codeGen only 
works correctly, if `numIterators() = 1`. For more iterators, the execution 
results in runtime assertions or segfaults.
The modified codeGen first calculates the iteration space, then multiplies to 
the number of dependencies in the depend clause and finally adds to the total 
number of iterator dependencies.

>From 655acc619286dba497aab3b59a3b189f47f83237 Mon Sep 17 00:00:00 2001
From: Joachim Jenke <je...@itc.rwth-aachen.de>
Date: Wed, 17 Jul 2024 17:08:59 +0200
Subject: [PATCH] Fix calculation of dependencies for multi-dimensional
 iteration space

---
 clang/lib/CodeGen/CGOpenMPRuntime.cpp   | 12 ++++++----
 clang/test/OpenMP/depend_iterator_bug.c | 29 +++++++++++++++++++++++++
 clang/test/OpenMP/task_codegen.c        |  3 ++-
 3 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp 
b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 652fb700fc6af..a3ade3780b39a 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -4259,14 +4259,18 @@ std::pair<llvm::Value *, Address> 
CGOpenMPRuntime::emitDependClause(
     // Include number of iterations, if any.
 
     if (const auto *IE = cast_or_null<OMPIteratorExpr>(D.IteratorExpr)) {
+      llvm::Value *ClauseIteratorSpace =
+          llvm::ConstantInt::get(CGF.IntPtrTy, 1);
       for (unsigned I = 0, E = IE->numOfIterators(); I < E; ++I) {
         llvm::Value *Sz = CGF.EmitScalarExpr(IE->getHelper(I).Upper);
         Sz = CGF.Builder.CreateIntCast(Sz, CGF.IntPtrTy, /*isSigned=*/false);
-        llvm::Value *NumClauseDeps = CGF.Builder.CreateNUWMul(
-            Sz, llvm::ConstantInt::get(CGF.IntPtrTy, D.DepExprs.size()));
-        NumOfRegularWithIterators =
-            CGF.Builder.CreateNUWAdd(NumOfRegularWithIterators, NumClauseDeps);
+        ClauseIteratorSpace = CGF.Builder.CreateNUWMul(Sz, 
ClauseIteratorSpace);
       }
+      llvm::Value *NumClauseDeps =
+          CGF.Builder.CreateNUWMul(ClauseIteratorSpace, 
+              llvm::ConstantInt::get(CGF.IntPtrTy, D.DepExprs.size()));
+      NumOfRegularWithIterators =
+          CGF.Builder.CreateNUWAdd(NumOfRegularWithIterators, NumClauseDeps);
       HasRegularWithIterators = true;
       continue;
     }
diff --git a/clang/test/OpenMP/depend_iterator_bug.c 
b/clang/test/OpenMP/depend_iterator_bug.c
index b4aaaac08374f..ff11d8a5d0e40 100644
--- a/clang/test/OpenMP/depend_iterator_bug.c
+++ b/clang/test/OpenMP/depend_iterator_bug.c
@@ -5,6 +5,7 @@
 
 int x[100];
 int y[100];
+int z[100][100];
 
 // CHECK-LABEL: @many_iterators_single_clause(
 // CHECK:    [[VLA:%.*]] = alloca [[STRUCT_KMP_DEPEND_INFO:%.*]], i64 10, 
align 16
@@ -24,3 +25,31 @@ void many_iterators_many_clauses(void) {
     {
     }
 }
+
+// CHECK-LABEL: @multidim_iterators_clause1(
+// CHECK:    [[VLA:%.*]] = alloca [[STRUCT_KMP_DEPEND_INFO:%.*]], i64 1, align 
16
+// CHECK:    = call i32 @__kmpc_omp_task_with_deps(ptr {{.*}}, i32 {{.*}}, ptr 
{{.*}}, i32 1, ptr {{.*}}, i32 0, ptr null)
+void multidim_iterators_clause1(void) {
+    #pragma omp task depend(iterator(i=0:1, j=0:1), in: z[i][j])
+    {
+    }
+}
+
+// CHECK-LABEL: @multidim_iterators_offset_clause(
+// CHECK:    [[VLA:%.*]] = alloca [[STRUCT_KMP_DEPEND_INFO:%.*]], i64 1, align 
16
+// CHECK:    = call i32 @__kmpc_omp_task_with_deps(ptr {{.*}}, i32 {{.*}}, ptr 
{{.*}}, i32 1, ptr {{.*}}, i32 0, ptr null)
+void multidim_iterators_offset_clause(void) {
+    #pragma omp task depend(iterator(i=5:6, j=10:11), in: z[i][j])
+    {
+    }
+}
+
+// CHECK-LABEL: @multidim_iterators_clause25(
+// CHECK:    [[VLA:%.*]] = alloca [[STRUCT_KMP_DEPEND_INFO:%.*]], i64 25, 
align 16
+// CHECK:    = call i32 @__kmpc_omp_task_with_deps(ptr {{.*}}, i32 {{.*}}, ptr 
{{.*}}, i32 25, ptr {{.*}}, i32 0, ptr null)
+void multidim_iterators_clause25(void) {
+    #pragma omp task depend(iterator(i=0:5, j=0:5), in: z[i][j])
+    {
+    }
+}
+
diff --git a/clang/test/OpenMP/task_codegen.c b/clang/test/OpenMP/task_codegen.c
index be404827ce901..0ca815c0eccf1 100644
--- a/clang/test/OpenMP/task_codegen.c
+++ b/clang/test/OpenMP/task_codegen.c
@@ -139,7 +139,8 @@ for (int i = 0; i < 10; ++i)
   // CHECK: [[EB_SUB_2_ADD_1_SUB:%.+]] = sub i32 [[EB_SUB_2_ADD]], 1
   // CHECK: [[EB_SUB_2_ADD_1_SUB_2_DIV:%.+]] = udiv i32 
[[EB_SUB_2_ADD_1_SUB]], 2
   // CHECK: [[ELEMS:%.+]] = zext i32 [[EB_SUB_2_ADD_1_SUB_2_DIV]] to i64
-  // CHECK: [[NELEMS:%.+]] = mul nuw i64 [[ELEMS]], 1
+  // CHECK: [[ELEMS2:%.+]] = mul nuw i64 [[ELEMS]], 1
+  // CHECK: [[NELEMS:%.+]] = mul nuw i64 [[ELEMS2]], 1
 
   // ITERATOR_TOTAL = NELEMS + 0;
   // CHECK: [[ITERATOR_TOTAL:%.+]] = add nuw i64 0, [[NELEMS]]

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to