summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2018-02-15 23:39:43 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2018-02-15 23:39:43 +0000
commitea33dee38c86348bdad35c68aed64b9fbcd47be5 (patch)
tree9398b66eae7b38eff0a9f88da6cff2c6eaa9f1f8
parentd345f7393914cb4a57b079836f0723002a06cc71 (diff)
downloadbcm5719-llvm-ea33dee38c86348bdad35c68aed64b9fbcd47be5.tar.gz
bcm5719-llvm-ea33dee38c86348bdad35c68aed64b9fbcd47be5.zip
[OPENMP] Fix PR36399: Crash on C code with ordered doacross construct.
Codegen for ordered with doacross construct might produce incorrect code because of missing cleanup scope for the construct. Without this scope the final runtime function call could be emitted in the wrong order that leads to incorrect codegen. llvm-svn: 325304
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp2
-rw-r--r--clang/test/OpenMP/ordered_doacross_codegen.c61
2 files changed, 63 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 052ebcaf389..b4cc7ad63ce 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -2230,6 +2230,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(
incrementProfileCounter(&S);
}
+ RunCleanupsScope DoacrossCleanupScope(*this);
bool Ordered = false;
if (auto *OrderedClause = S.getSingleClause<OMPOrderedClause>()) {
if (OrderedClause->getNumForLoops())
@@ -2366,6 +2367,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(
return CGF.Builder.CreateIsNotNull(
CGF.EmitLoadOfScalar(IL, S.getLocStart()));
});
+ DoacrossCleanupScope.ForceCleanup();
// We're now done with the loop, so jump to the continuation block.
if (ContBlock) {
EmitBranch(ContBlock);
diff --git a/clang/test/OpenMP/ordered_doacross_codegen.c b/clang/test/OpenMP/ordered_doacross_codegen.c
new file mode 100644
index 00000000000..c12df2638f8
--- /dev/null
+++ b/clang/test/OpenMP/ordered_doacross_codegen.c
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -triple x86_64-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -triple x86_64-unknown-unknown -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -fopenmp-simd -triple x86_64-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -triple x86_64-unknown-unknown -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
+// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+// CHECK: [[KMP_DIM:%.+]] = type { i64, i64, i64 }
+extern int n;
+int a[10], b[10], c[10], d[10];
+void foo();
+
+// CHECK-LABEL: @main()
+int main() {
+ int i;
+// CHECK: [[DIMS:%.+]] = alloca [[KMP_DIM]],
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT:%.+]])
+// CHECK: icmp
+// CHECK-NEXT: br i1 %
+// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
+// CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 [[CAST]], i8 0, i64 24, i1 false)
+// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], i32 0, i32 1
+// CHECK: store i64 %{{.+}}, i64* %
+// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], i32 0, i32 2
+// CHECK: store i64 1, i64* %
+// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8*
+// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], i32 1, i8* [[CAST]])
+// CHECK: call void @__kmpc_for_static_init_4(
+#pragma omp for ordered(1)
+ for (i = 0; i < n; ++i) {
+ a[i] = b[i] + 1;
+ foo();
+// CHECK: call void [[FOO:.+]](
+// CHECK: load i32, i32* [[CNT:%.+]],
+// CHECK-NEXT: sext i32 %{{.+}} to i64
+// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
+// CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32 [[GTID]], i64* [[TMP]])
+#pragma omp ordered depend(source)
+ c[i] = c[i] + 1;
+ foo();
+// CHECK: call void [[FOO]]
+// CHECK: load i32, i32* [[CNT]],
+// CHECK-NEXT: sub nsw i32 %{{.+}}, 2
+// CHECK-NEXT: sext i32 %{{.+}} to i64
+// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]],
+// CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 [[GTID]], i64* [[TMP]])
+#pragma omp ordered depend(sink : i - 2)
+ d[i] = a[i - 2];
+ }
+ // CHECK: call void @__kmpc_for_static_fini(
+ // CHECK: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]])
+ // CHECK: ret i32 0
+ return 0;
+}
+#endif // HEADER
OpenPOWER on IntegriCloud