-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[OpenMP] Fix calculation of dependencies for multi-dimensional iteration space #99347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: Joachim (jprotze) ChangesThe expectation for multiple iterators used in a single depend clause ( Full diff: https://github.com/llvm/llvm-project/pull/99347.diff 3 Files Affected:
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]]
|
@llvm/pr-subscribers-clang-codegen Author: Joachim (jprotze) ChangesThe expectation for multiple iterators used in a single depend clause ( Full diff: https://github.com/llvm/llvm-project/pull/99347.diff 3 Files Affected:
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]]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
655acc6
to
b45379e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG
b45379e
to
033b032
Compare
…ion space (#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.
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, ifnumIterators() = 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.