From 44a6b3a4b69185d3cf0076ae3cad765a10205bc0 Mon Sep 17 00:00:00 2001 From: CHANDRA GHALE Date: Mon, 11 Nov 2024 14:34:16 +0530 Subject: [PATCH] Fix for codegen Crash in Clang when using locator omp_all_memory with depobj construct (#114221) A codegen crash is occurring when a depend object was initialized with omp_all_memory in the depobj directive. https://github.com/llvm/llvm-project/issues/114214(url) The root cause of issue looks to be the improper handling of the dependency list when omp_all_memory was specified. The change introduces the use of OMPTaskDataTy to manage dependencies. The buildDependences function is called to construct the dependency list, and the list is iterated over to emit and store the dependencies. Reduced Test Case : ``` #include int main() { omp_depend_t obj; #pragma omp depobj(obj) depend(inout: omp_all_memory) } ``` ``` #1 0x0000000003de6623 SignalHandler(int) Signals.cpp:0:0 #2 0x00007f8e4a6b990f (/lib64/libpthread.so.0+0x1690f) #3 0x00007f8e4a117d2a raise (/lib64/libc.so.6+0x4ad2a) #4 0x00007f8e4a1193e4 abort (/lib64/libc.so.6+0x4c3e4) #5 0x00007f8e4a10fc69 __assert_fail_base (/lib64/libc.so.6+0x42c69) #6 0x00007f8e4a10fcf1 __assert_fail (/lib64/libc.so.6+0x42cf1) #7 0x0000000004114367 clang::CodeGen::CodeGenFunction::EmitOMPDepobjDirective(clang::OMPDepobjDirective const&) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x4114367) #8 0x00000000040f8fac clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x40f8fac) #9 0x00000000040ff4fb clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x40ff4fb) #10 0x00000000041847b2 clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::Stmt const*) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x41847b2) #11 0x0000000004199e4a clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x4199e4a) #12 0x00000000041f7b9d clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x41f7b9d) #13 0x00000000041f16a3 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x41f16a3) #14 0x00000000041fd954 clang::CodeGen::CodeGenModule::EmitDeferred() (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x41fd954) #15 0x0000000004200277 clang::CodeGen::CodeGenModule::Release() (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x4200277) #16 0x00000000046b6a49 (anonymous namespace)::CodeGeneratorImpl::HandleTranslationUnit(clang::ASTContext&) ModuleBuilder.cpp:0:0 #17 0x00000000046b4cb6 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x46b4cb6) #18 0x0000000006204d5c clang::ParseAST(clang::Sema&, bool, bool) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x6204d5c) #19 0x000000000496b278 clang::FrontendAction::Execute() (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x496b278) #20 0x00000000048dd074 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x48dd074) #21 0x0000000004a38092 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0x4a38092) #22 0x0000000000fd4e9c cc1_main(llvm::ArrayRef, char const*, void*) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0xfd4e9c) #23 0x0000000000fcca73 ExecuteCC1Tool(llvm::SmallVectorImpl&, llvm::ToolContext const&) driver.cpp:0:0 #24 0x0000000000fd140c clang_main(int, char**, llvm::ToolContext const&) (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0xfd140c) #25 0x0000000000ee2ef3 main (/opt/cray/pe/cce/18.0.1/cce-clang/x86_64/bin/clang-18+0xee2ef3) #26 0x00007f8e4a10224c __libc_start_main (/lib64/libc.so.6+0x3524c) #27 0x0000000000fcaae9 _start /home/abuild/rpmbuild/BUILD/glibc-2.31/csu/../sysdeps/x86_64/start.S:120:0 clang: error: unable to execute command: Aborted ``` --------- Co-authored-by: Chandra Ghale --- clang/lib/CodeGen/CGStmtOpenMP.cpp | 14 ++++++------ clang/test/OpenMP/depobj_codegen.cpp | 32 ++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 1c32a675380c7..390516fea3849 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -5556,12 +5556,14 @@ void CodeGenFunction::EmitOMPDepobjDirective(const OMPDepobjDirective &S) { const auto *DO = S.getSingleClause(); LValue DOLVal = EmitLValue(DO->getDepobj()); if (const auto *DC = S.getSingleClause()) { - OMPTaskDataTy::DependData Dependencies(DC->getDependencyKind(), - DC->getModifier()); - Dependencies.DepExprs.append(DC->varlist_begin(), DC->varlist_end()); - Address DepAddr = CGM.getOpenMPRuntime().emitDepobjDependClause( - *this, Dependencies, DC->getBeginLoc()); - EmitStoreOfScalar(DepAddr.emitRawPointer(*this), DOLVal); + // Build list and emit dependences + OMPTaskDataTy Data; + buildDependences(S, Data); + for (auto &Dep : Data.Dependences) { + Address DepAddr = CGM.getOpenMPRuntime().emitDepobjDependClause( + *this, Dep, DC->getBeginLoc()); + EmitStoreOfScalar(DepAddr.emitRawPointer(*this), DOLVal); + } return; } if (const auto *DC = S.getSingleClause()) { diff --git a/clang/test/OpenMP/depobj_codegen.cpp b/clang/test/OpenMP/depobj_codegen.cpp index 92751ac44b8c7..b3bcd76e237dc 100644 --- a/clang/test/OpenMP/depobj_codegen.cpp +++ b/clang/test/OpenMP/depobj_codegen.cpp @@ -17,6 +17,15 @@ typedef void *omp_depend_t; void foo() {} +void tmainc(){ + omp_depend_t obj; +#pragma omp depobj(obj) depend(inout: omp_all_memory) +{ + volatile omp_depend_t temp = obj; + char* char_ptr = reinterpret_cast(temp); + char_ptr[0] = 1; +} +} template T tmain(T argc) { @@ -35,10 +44,25 @@ int main(int argc, char **argv) { #pragma omp depobj(b) destroy #pragma omp depobj(b) update(mutexinoutset) #pragma omp depobj(a) depend(iterator(char *p = argv[argc]:argv[0]:-1), out: p[0]) - (void)tmain(a), tmain(b); + (void)tmain(a), tmain(b); + tmainc(); return 0; } - +// CHECK-LABEL: tmainc +// CHECK: [[D_ADDR:%obj]] = alloca ptr, +// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num( +// CHECK: [[DEP_ADDR_ADDR2:%.+]] = call ptr @__kmpc_alloc(i32 [[GTID]], i64 48, ptr null) +// CHECK: [[SZ_DEOOBJ:%.+]] = getelementptr inbounds nuw %struct.kmp_depend_info, ptr [[DEP_ADDR_ADDR2]], i{{.+}} 0, i{{.+}} 0 +// CHECK: store i64 1, ptr [[SZ_DEOOBJ]], align 8 +// CHECK: [[DEPOBJ_BASE_ADDR:%.+]] = getelementptr %struct.kmp_depend_info, ptr [[DEP_ADDR_ADDR2]], i{{.+}} 1 +// CHECK: [[ADDR_ONE:%.+]] = getelementptr inbounds nuw %struct.kmp_depend_info, ptr [[DEPOBJ_BASE_ADDR]], i{{.+}} 0, i{{.+}} 0 +// CHECK: store i64 0, ptr [[ADDR_ONE]], align 8 +// CHECK: [[SZ_ADDR:%.+]] = getelementptr inbounds nuw %struct.kmp_depend_info, ptr [[DEPOBJ_BASE_ADDR]], i{{.+}} 0, i{{.+}} 1 +// CHECK: store i64 0, ptr [[SZ_ADDR]], align 8 +// CHECK: [[SZ_ADDR_NEW:%.+]] = getelementptr inbounds nuw %struct.kmp_depend_info, ptr [[DEPOBJ_BASE_ADDR]], i{{.+}} 0, i{{.+}} 2 +// CHECK: store {{i[0-9]+}} {{-?[0-9]+}}, ptr [[SZ_ADDR_NEW]], align 8 +// CHECK: [[DEP_NEW:%.+]] = getelementptr %struct.kmp_depend_info, ptr [[DEP_ADDR_ADDR2]], i{{.+}} 1 +// CHECK: store ptr [[DEP_NEW]], ptr [[D_ADDR]], align 8 // CHECK-LABEL: @main // CHECK: [[B_ADDR:%b]] = alloca ptr, // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num( @@ -69,6 +93,8 @@ int main(int argc, char **argv) { // CHECK: [[NUMDEPS_ADDR:%.+]] = getelementptr inbounds nuw %struct.kmp_depend_info, ptr [[NUMDEPS_BASE]], i{{.+}} 0, i{{.+}} 0 // CHECK: [[NUMDEPS:%.+]] = load i64, ptr [[NUMDEPS_ADDR]], align 8 // CHECK: [[END:%.+]] = getelementptr %struct.kmp_depend_info, ptr [[B_BASE]], i64 [[NUMDEPS]] + + // CHECK: br label %[[BODY:.+]] // CHECK: [[BODY]]: // CHECK: [[EL:%.+]] = phi ptr [ [[B_BASE]], %{{.+}} ], [ [[EL_NEXT:%.+]], %[[BODY]] ] @@ -228,6 +254,8 @@ int main(int argc, char **argv) { // CHECK: [[EL_NEXT]] = getelementptr %struct.kmp_depend_info, ptr [[EL]], i{{.+}} 1 // CHECK: [[IS_DONE:%.+]] = icmp eq ptr [[EL_NEXT]], [[END]] // CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[BODY]] + // CHECK: [[DONE]]: + #endif