diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index b088251e0cf3c..85de5dbedf331 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -2024,22 +2024,29 @@ void CGOpenMPRuntime::emitCriticalRegion(CodeGenFunction &CGF, // Prepare arguments and build a call to __kmpc_critical if (!CGF.HaveInsertPoint()) return; + llvm::FunctionCallee RuntimeFcn = OMPBuilder.getOrCreateRuntimeFunction( + CGM.getModule(), + Hint ? OMPRTL___kmpc_critical_with_hint : OMPRTL___kmpc_critical); + llvm::Value *LockVar = getCriticalRegionLock(CriticalName); + unsigned LockVarArgIdx = 2; + if (cast(LockVar)->getAddressSpace() != + RuntimeFcn.getFunctionType() + ->getParamType(LockVarArgIdx) + ->getPointerAddressSpace()) + LockVar = CGF.Builder.CreateAddrSpaceCast( + LockVar, RuntimeFcn.getFunctionType()->getParamType(LockVarArgIdx)); llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), - getCriticalRegionLock(CriticalName)}; + LockVar}; llvm::SmallVector EnterArgs(std::begin(Args), std::end(Args)); if (Hint) { EnterArgs.push_back(CGF.Builder.CreateIntCast( CGF.EmitScalarExpr(Hint), CGM.Int32Ty, /*isSigned=*/false)); } - CommonActionTy Action( - OMPBuilder.getOrCreateRuntimeFunction( - CGM.getModule(), - Hint ? OMPRTL___kmpc_critical_with_hint : OMPRTL___kmpc_critical), - EnterArgs, - OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(), - OMPRTL___kmpc_end_critical), - Args); + CommonActionTy Action(RuntimeFcn, EnterArgs, + OMPBuilder.getOrCreateRuntimeFunction( + CGM.getModule(), OMPRTL___kmpc_end_critical), + Args); CriticalOpGen.setAction(Action); emitInlinedDirective(CGF, OMPD_critical, CriticalOpGen); } diff --git a/clang/test/OpenMP/spirv_target_codegen_basic.cpp b/clang/test/OpenMP/spirv_target_codegen_basic.cpp index fb2810e88c063..2cfd541f8c52d 100644 --- a/clang/test/OpenMP/spirv_target_codegen_basic.cpp +++ b/clang/test/OpenMP/spirv_target_codegen_basic.cpp @@ -6,12 +6,18 @@ // CHECK: @__omp_offloading_{{.*}}_dynamic_environment = weak_odr protected addrspace(1) global %struct.DynamicEnvironmentTy zeroinitializer // CHECK: @__omp_offloading_{{.*}}_kernel_environment = weak_odr protected addrspace(1) constant %struct.KernelEnvironmentTy +// CHECK: @"_gomp_critical_user_$var" = common global [8 x i32] zeroinitializer, align 8 + // CHECK: define weak_odr protected spir_kernel void @__omp_offloading_{{.*}} +// CHECK: call spir_func addrspace(9) void @__kmpc_critical(ptr addrspace(4) addrspacecast (ptr addrspace(1) @{{.*}} to ptr addrspace(4)), i32 %{{.*}}, ptr addrspace(4) addrspacecast (ptr @"_gomp_critical_user_$var" to ptr addrspace(4))) +// CHECK: call spir_func addrspace(9) void @__kmpc_end_critical(ptr addrspace(4) addrspacecast (ptr addrspace(1) @{{.*}} to ptr addrspace(4)), i32 %{{.*}}, ptr addrspace(4) addrspacecast (ptr @"_gomp_critical_user_$var" to ptr addrspace(4))) + int main() { int ret = 0; #pragma omp target for(int i = 0; i < 5; i++) + #pragma omp critical ret++; return ret; } diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h index 9c37775af52f8..d5057aa596b62 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h @@ -3681,7 +3681,7 @@ class OpenMPIRBuilder { /// \param Name Name of the variable. LLVM_ABI GlobalVariable * getOrCreateInternalVariable(Type *Ty, const StringRef &Name, - unsigned AddressSpace = 0); + std::optional AddressSpace = 0); }; /// Class to represented the control flow structure of an OpenMP canonical loop. diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp index 4e00daf50c147..f3200e40e5ba2 100644 --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -8577,9 +8577,8 @@ OpenMPIRBuilder::createPlatformSpecificName(ArrayRef Parts) const { Config.separator()); } -GlobalVariable * -OpenMPIRBuilder::getOrCreateInternalVariable(Type *Ty, const StringRef &Name, - unsigned AddressSpace) { +GlobalVariable *OpenMPIRBuilder::getOrCreateInternalVariable( + Type *Ty, const StringRef &Name, std::optional AddressSpace) { auto &Elem = *InternalVars.try_emplace(Name, nullptr).first; if (Elem.second) { assert(Elem.second->getValueType() == Ty && @@ -8590,24 +8589,17 @@ OpenMPIRBuilder::getOrCreateInternalVariable(Type *Ty, const StringRef &Name, // create different versions of the function for different OMP internal // variables. const DataLayout &DL = M.getDataLayout(); - // TODO: Investigate why AMDGPU expects AS 0 for globals even though the - // default global AS is 1. - // See double-target-call-with-declare-target.f90 and - // declare-target-vars-in-target-region.f90 libomptarget - // tests. - unsigned AddressSpaceVal = AddressSpace ? AddressSpace - : M.getTargetTriple().isAMDGPU() - ? 0 - : DL.getDefaultGlobalsAddressSpace(); + unsigned AddressSpaceVal = + AddressSpace ? *AddressSpace : DL.getDefaultGlobalsAddressSpace(); auto Linkage = this->M.getTargetTriple().getArch() == Triple::wasm32 ? GlobalValue::InternalLinkage : GlobalValue::CommonLinkage; auto *GV = new GlobalVariable(M, Ty, /*IsConstant=*/false, Linkage, Constant::getNullValue(Ty), Elem.first(), /*InsertBefore=*/nullptr, - GlobalValue::NotThreadLocal, AddressSpace); + GlobalValue::NotThreadLocal, AddressSpaceVal); const llvm::Align TypeAlign = DL.getABITypeAlign(Ty); - const llvm::Align PtrAlign = DL.getPointerABIAlignment(AddressSpace); + const llvm::Align PtrAlign = DL.getPointerABIAlignment(AddressSpaceVal); GV->setAlignment(std::max(TypeAlign, PtrAlign)); Elem.second = GV; } diff --git a/revert_patches.txt b/revert_patches.txt index b88b846f64b68..9e465ba90ae6a 100644 --- a/revert_patches.txt +++ b/revert_patches.txt @@ -5,6 +5,3 @@ d57230c7 [AMDGPU][MC] Disallow op_sel in some VOP3P dot instructions (#100485) breaks build of ROCmValidationSuite [C2y] Support WG14 N3457, the __COUNTER__ macro (#162662) --- -breaks fortran declare-target-link1 -[OMPIRBuilder] Fix addrspace of internal critical section lock (#166459 ----