From 5288ea1496b01a95b269ac6d6825bedb5c7a14c7 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Wed, 11 Oct 2017 15:29:40 +0000 Subject: [PATCH] [OPENMP] Fix PR34916: Crash on mixing taskloop|tasks directives. If both taskloop and task directives are used at the same time in one program, we may ran into the situation when the particular type for task directive is reused for taskloop directives. Patch fixes this problem. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@315464 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGOpenMPRuntime.cpp | 17 ++++++++++++++--- lib/CodeGen/CGOpenMPRuntime.h | 4 ++++ test/OpenMP/taskloop_codegen.cpp | 4 ++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp index 82a094e664..8052b9d0c8 100644 --- a/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/lib/CodeGen/CGOpenMPRuntime.cpp @@ -4268,9 +4268,20 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, // Build type kmp_routine_entry_t (if not built yet). emitKmpRoutineEntryT(KmpInt32Ty); // Build type kmp_task_t (if not built yet). - if (KmpTaskTQTy.isNull()) { - KmpTaskTQTy = C.getRecordType(createKmpTaskTRecordDecl( - CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy)); + if (isOpenMPTaskLoopDirective(D.getDirectiveKind())) { + if (SavedKmpTaskloopTQTy.isNull()) { + SavedKmpTaskloopTQTy = C.getRecordType(createKmpTaskTRecordDecl( + CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy)); + } + KmpTaskTQTy = SavedKmpTaskloopTQTy; + } else if (D.getDirectiveKind() == OMPD_task) { + assert(D.getDirectiveKind() == OMPD_task && + "Expected taskloop or task directive"); + if (SavedKmpTaskTQTy.isNull()) { + SavedKmpTaskTQTy = C.getRecordType(createKmpTaskTRecordDecl( + CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy)); + } + KmpTaskTQTy = SavedKmpTaskTQTy; } auto *KmpTaskTQTyRD = cast(KmpTaskTQTy->getAsTagDecl()); // Build particular struct kmp_task_t for the given task. diff --git a/lib/CodeGen/CGOpenMPRuntime.h b/lib/CodeGen/CGOpenMPRuntime.h index 4a93e79754..94a1438413 100644 --- a/lib/CodeGen/CGOpenMPRuntime.h +++ b/lib/CodeGen/CGOpenMPRuntime.h @@ -318,6 +318,10 @@ private: /// deconstructors of firstprivate C++ objects */ /// } kmp_task_t; QualType KmpTaskTQTy; + /// Saved kmp_task_t for task directive. + QualType SavedKmpTaskTQTy; + /// Saved kmp_task_t for taskloop-based directive. + QualType SavedKmpTaskloopTQTy; /// \brief Type typedef struct kmp_depend_info { /// kmp_intptr_t base_addr; /// size_t len; diff --git a/test/OpenMP/taskloop_codegen.cpp b/test/OpenMP/taskloop_codegen.cpp index 8de52023f3..94cf5365d8 100644 --- a/test/OpenMP/taskloop_codegen.cpp +++ b/test/OpenMP/taskloop_codegen.cpp @@ -8,6 +8,10 @@ // CHECK-LABEL: @main int main(int argc, char **argv) { // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEFLOC:@.+]]) +// CHECK: call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], +// CHECK: call i32 @__kmpc_omp_task(%ident_t* [[DEFLOC]], i32 [[GTID]], +#pragma omp task + ; // CHECK: call void @__kmpc_taskgroup(%ident_t* [[DEFLOC]], i32 [[GTID]]) // CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 33, i64 80, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK1:@.+]] to i32 (i32, i8*)*)) // CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]* -- 2.40.0