jhuber6 created this revision. jhuber6 added reviewers: jdoerfert, JonChesterfield, ronlieb, ABataev. Herald added subscribers: asavonic, guansong, tpr, yaxunl. Herald added a project: All. jhuber6 requested review of this revision. Herald added subscribers: cfe-commits, sstefan1. Herald added a project: clang.
The default construction of constructor functions by LLVM tends to make them have internal linkage. When we call a ctor / dtor function in the target region we are actually creating a kernel that is called at registration. Because the ctor is a kernel we need to make sure it's externally visible so we can actually call it. This prevented AMDGPU from correctly using constructors while NVPTX could use them simply because it ignored internal visibility. Fixes #54091 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D122504 Files: clang/lib/CodeGen/CGOpenMPRuntime.cpp clang/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp Index: clang/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp =================================================================== --- clang/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp +++ clang/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp @@ -44,7 +44,7 @@ static int c = foo() + bar() + baz(); #pragma omp declare target (c) // HOST-DAG: @[[C_CTOR:__omp_offloading__.+_c_l44_ctor]] = private constant i8 0 -// DEVICE-DAG: define internal void [[C_CTOR:@__omp_offloading__.+_c_l44_ctor]]() +// DEVICE-DAG: define weak_odr dso_local void [[C_CTOR:@__omp_offloading__.+_c_l44_ctor]]() // DEVICE-DAG: call noundef i32 [[FOO]]() // DEVICE-DAG: call noundef i32 [[BAR]]() // DEVICE-DAG: call noundef i32 [[BAZ]]() @@ -61,14 +61,14 @@ S cd = doo() + car() + caz() + baz(); #pragma omp end declare target // HOST-DAG: @[[CD_CTOR:__omp_offloading__.+_cd_l61_ctor]] = private constant i8 0 -// DEVICE-DAG: define internal void [[CD_CTOR:@__omp_offloading__.+_cd_l61_ctor]]() +// DEVICE-DAG: define weak_odr dso_local void [[CD_CTOR:@__omp_offloading__.+_cd_l61_ctor]]() // DEVICE-DAG: call noundef i32 [[DOO]]() // DEVICE-DAG: call noundef i32 [[CAR]]() // DEVICE-DAG: call noundef i32 [[CAZ]]() // DEVICE-DAG: ret void // HOST-DAG: @[[CD_DTOR:__omp_offloading__.+_cd_l61_dtor]] = private constant i8 0 -// DEVICE-DAG: define internal void [[CD_DTOR:@__omp_offloading__.+_cd_l61_dtor]]() +// DEVICE-DAG: define weak_odr dso_local void [[CD_DTOR:@__omp_offloading__.+_cd_l61_dtor]]() // DEVICE-DAG: call void // DEVICE-DAG: ret void Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp =================================================================== --- clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -3022,6 +3022,13 @@ // This could happen if the device compilation is invoked standalone. if (!hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum)) return; + + // If we are registering a ctor / dtor we need to make sure it's externally + // visible so we can call it from the host. + if (Flags == OMPTargetRegionEntryCtor || Flags == OMPTargetRegionEntryDtor) + if (llvm::GlobalValue *GV = dyn_cast<llvm::GlobalValue>(Addr)) + GV->setLinkage(llvm::GlobalValue::WeakODRLinkage); + auto &Entry = OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum]; Entry.setAddress(Addr);
Index: clang/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp =================================================================== --- clang/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp +++ clang/test/OpenMP/nvptx_declare_target_var_ctor_dtor_codegen.cpp @@ -44,7 +44,7 @@ static int c = foo() + bar() + baz(); #pragma omp declare target (c) // HOST-DAG: @[[C_CTOR:__omp_offloading__.+_c_l44_ctor]] = private constant i8 0 -// DEVICE-DAG: define internal void [[C_CTOR:@__omp_offloading__.+_c_l44_ctor]]() +// DEVICE-DAG: define weak_odr dso_local void [[C_CTOR:@__omp_offloading__.+_c_l44_ctor]]() // DEVICE-DAG: call noundef i32 [[FOO]]() // DEVICE-DAG: call noundef i32 [[BAR]]() // DEVICE-DAG: call noundef i32 [[BAZ]]() @@ -61,14 +61,14 @@ S cd = doo() + car() + caz() + baz(); #pragma omp end declare target // HOST-DAG: @[[CD_CTOR:__omp_offloading__.+_cd_l61_ctor]] = private constant i8 0 -// DEVICE-DAG: define internal void [[CD_CTOR:@__omp_offloading__.+_cd_l61_ctor]]() +// DEVICE-DAG: define weak_odr dso_local void [[CD_CTOR:@__omp_offloading__.+_cd_l61_ctor]]() // DEVICE-DAG: call noundef i32 [[DOO]]() // DEVICE-DAG: call noundef i32 [[CAR]]() // DEVICE-DAG: call noundef i32 [[CAZ]]() // DEVICE-DAG: ret void // HOST-DAG: @[[CD_DTOR:__omp_offloading__.+_cd_l61_dtor]] = private constant i8 0 -// DEVICE-DAG: define internal void [[CD_DTOR:@__omp_offloading__.+_cd_l61_dtor]]() +// DEVICE-DAG: define weak_odr dso_local void [[CD_DTOR:@__omp_offloading__.+_cd_l61_dtor]]() // DEVICE-DAG: call void // DEVICE-DAG: ret void Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp =================================================================== --- clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -3022,6 +3022,13 @@ // This could happen if the device compilation is invoked standalone. if (!hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum)) return; + + // If we are registering a ctor / dtor we need to make sure it's externally + // visible so we can call it from the host. + if (Flags == OMPTargetRegionEntryCtor || Flags == OMPTargetRegionEntryDtor) + if (llvm::GlobalValue *GV = dyn_cast<llvm::GlobalValue>(Addr)) + GV->setLinkage(llvm::GlobalValue::WeakODRLinkage); + auto &Entry = OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum]; Entry.setAddress(Addr);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits