-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[OpenMP] Conditional modifier on lastprivate clause is producing incorrect result in C mode #156004
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: CHANDRA GHALE (chandraghale) ChangesConditional modifier on lastprivate clause is producing incorrect result when compiled with clang( C compiler). IR is not emitting while compilation with C compiler.
Full diff: https://github.com/llvm/llvm-project/pull/156004.diff 2 Files Affected:
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 193710bef2d16..d37712f27ed5e 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -5183,6 +5183,11 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS);
}
}
+ // OpenMP: Handle lastprivate(condition:) in scalar assignment
+ if (CGF.getLangOpts().OpenMP) {
+ CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF,
+ E->getLHS());
+ }
// If the result is clearly ignored, return now.
if (Ignore)
diff --git a/clang/test/OpenMP/for_lst_private_codegen_c.c b/clang/test/OpenMP/for_lst_private_codegen_c.c
new file mode 100644
index 0000000000000..c56c5b6fb9351
--- /dev/null
+++ b/clang/test/OpenMP/for_lst_private_codegen_c.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -verify -x c -triple x86_64-unknown-linux-gnu -fopenmp -fopenmp-version=52 -emit-llvm -o - %s | FileCheck %s
+// expected-no-diagnostics
+
+#define N 100
+int A[N];
+
+void condlastprivate() {
+ int x, y, z, k;
+ x = y = z = k = 0;
+
+ #pragma omp parallel for lastprivate(conditional: x,y,z) lastprivate(k)
+ for (k = 0; k < N; k++) {
+ if ((k > 2) && (k < 6)) {
+ x = A[k];
+ z = A[k] + 111;
+ } else {
+ y = A[k] + 222;
+ }
+ }
+}
+
+int main() {
+ for (int i = 0; i < N; i++)
+ A[i] = i;
+ condlastprivate();
+ return 0;
+}
+
+// CHECK: @.pl_cond.x_[[ID:[0-9]+]].iv = common global i32 0, align 4
+// CHECK: @pl_cond.x_[[ID]] = common global i32 0, align 4
+// CHECK: @.gomp_critical_user_pl_cond.x_[[ID]].var = common global [8 x i32] zeroinitializer, align 8
+
+// CHECK: @.pl_cond.z_[[ID]].iv = common global i32 0, align 4
+// CHECK: @pl_cond.z_[[ID]] = common global i32 0, align 4
+// CHECK: @.gomp_critical_user_pl_cond.z_[[ID]].var = common global [8 x i32] zeroinitializer, align 8
+
+// CHECK: @.pl_cond.y_[[ID]].iv = common global i32 0, align 4
+// CHECK: @pl_cond.y_[[ID]] = common global i32 0, align 4
+// CHECK: @.gomp_critical_user_pl_cond.y_[[ID]].var = common global [8 x i32] zeroinitializer, align 8
+
+// CHECK-LABEL: define internal void @condlastprivate.omp_outlined(
+// CHECK: call void @__kmpc_critical(ptr @2, {{.*}}, ptr @.gomp_critical_user_pl_cond.x_[[ID]].var)
+// CHECK: store i32 %{{[0-9]+}}, ptr @pl_cond.x_[[ID]], align 4
+// CHECK: call void @__kmpc_end_critical(ptr @2, {{.*}}, ptr @.gomp_critical_user_pl_cond.x_[[ID]].var)
+
+// CHECK: call void @__kmpc_critical(ptr @2, {{.*}}, ptr @.gomp_critical_user_pl_cond.z_[[ID]].var)
+// CHECK: store i32 %{{[0-9]+}}, ptr @pl_cond.z_[[ID]], align 4
+// CHECK: call void @__kmpc_end_critical(ptr @2, {{.*}}, ptr @.gomp_critical_user_pl_cond.z_[[ID]].var)
+
+// CHECK: call void @__kmpc_critical(ptr @2, {{.*}}, ptr @.gomp_critical_user_pl_cond.y_[[ID]].var)
+// CHECK: store i32 %{{[0-9]+}}, ptr @pl_cond.y_[[ID]], align 4
+// CHECK: call void @__kmpc_end_critical(ptr @2, {{.*}}, ptr @.gomp_critical_user_pl_cond.y_[[ID]].var)
+
|
@llvm/pr-subscribers-clang-codegen Author: CHANDRA GHALE (chandraghale) ChangesConditional modifier on lastprivate clause is producing incorrect result when compiled with clang( C compiler). IR is not emitting while compilation with C compiler.
Full diff: https://github.com/llvm/llvm-project/pull/156004.diff 2 Files Affected:
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 193710bef2d16..d37712f27ed5e 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -5183,6 +5183,11 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS);
}
}
+ // OpenMP: Handle lastprivate(condition:) in scalar assignment
+ if (CGF.getLangOpts().OpenMP) {
+ CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF,
+ E->getLHS());
+ }
// If the result is clearly ignored, return now.
if (Ignore)
diff --git a/clang/test/OpenMP/for_lst_private_codegen_c.c b/clang/test/OpenMP/for_lst_private_codegen_c.c
new file mode 100644
index 0000000000000..c56c5b6fb9351
--- /dev/null
+++ b/clang/test/OpenMP/for_lst_private_codegen_c.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -verify -x c -triple x86_64-unknown-linux-gnu -fopenmp -fopenmp-version=52 -emit-llvm -o - %s | FileCheck %s
+// expected-no-diagnostics
+
+#define N 100
+int A[N];
+
+void condlastprivate() {
+ int x, y, z, k;
+ x = y = z = k = 0;
+
+ #pragma omp parallel for lastprivate(conditional: x,y,z) lastprivate(k)
+ for (k = 0; k < N; k++) {
+ if ((k > 2) && (k < 6)) {
+ x = A[k];
+ z = A[k] + 111;
+ } else {
+ y = A[k] + 222;
+ }
+ }
+}
+
+int main() {
+ for (int i = 0; i < N; i++)
+ A[i] = i;
+ condlastprivate();
+ return 0;
+}
+
+// CHECK: @.pl_cond.x_[[ID:[0-9]+]].iv = common global i32 0, align 4
+// CHECK: @pl_cond.x_[[ID]] = common global i32 0, align 4
+// CHECK: @.gomp_critical_user_pl_cond.x_[[ID]].var = common global [8 x i32] zeroinitializer, align 8
+
+// CHECK: @.pl_cond.z_[[ID]].iv = common global i32 0, align 4
+// CHECK: @pl_cond.z_[[ID]] = common global i32 0, align 4
+// CHECK: @.gomp_critical_user_pl_cond.z_[[ID]].var = common global [8 x i32] zeroinitializer, align 8
+
+// CHECK: @.pl_cond.y_[[ID]].iv = common global i32 0, align 4
+// CHECK: @pl_cond.y_[[ID]] = common global i32 0, align 4
+// CHECK: @.gomp_critical_user_pl_cond.y_[[ID]].var = common global [8 x i32] zeroinitializer, align 8
+
+// CHECK-LABEL: define internal void @condlastprivate.omp_outlined(
+// CHECK: call void @__kmpc_critical(ptr @2, {{.*}}, ptr @.gomp_critical_user_pl_cond.x_[[ID]].var)
+// CHECK: store i32 %{{[0-9]+}}, ptr @pl_cond.x_[[ID]], align 4
+// CHECK: call void @__kmpc_end_critical(ptr @2, {{.*}}, ptr @.gomp_critical_user_pl_cond.x_[[ID]].var)
+
+// CHECK: call void @__kmpc_critical(ptr @2, {{.*}}, ptr @.gomp_critical_user_pl_cond.z_[[ID]].var)
+// CHECK: store i32 %{{[0-9]+}}, ptr @pl_cond.z_[[ID]], align 4
+// CHECK: call void @__kmpc_end_critical(ptr @2, {{.*}}, ptr @.gomp_critical_user_pl_cond.z_[[ID]].var)
+
+// CHECK: call void @__kmpc_critical(ptr @2, {{.*}}, ptr @.gomp_critical_user_pl_cond.y_[[ID]].var)
+// CHECK: store i32 %{{[0-9]+}}, ptr @pl_cond.y_[[ID]], align 4
+// CHECK: call void @__kmpc_end_critical(ptr @2, {{.*}}, ptr @.gomp_critical_user_pl_cond.y_[[ID]].var)
+
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Conditional modifier on lastprivate clause is producing incorrect result when compiled with clang( C compiler). IR is not emitting while compilation with C compiler.
However it is working correctly with clang++
The OpenMP hook that emits the conditional modifier (checkAndEmitLastprivateConditional) is skipped in C because assignment is a prvalue and takes the scalar path.
Original Codegen Support : eddb8