Skip to content

Commit c17a839

Browse files
authored
[OMPIRBuilder] Fix addrspace of internal critical section lock (llvm#166459)
First, for internal variables, they are always global, so use the global AS by default unless specified otherwise. We can't really use `0` as a default like we do now because that has an actual meaning on some targets, so we really need specified vs unspecified, so I used `std::optional` which is already used in many places in OMPIRBuilder. Second, for the critical lock variable, add an addrspace cast if needed. Signed-off-by: Nick Sarnie <[email protected]>
1 parent 69c8756 commit c17a839

File tree

5 files changed

+31
-17
lines changed

5 files changed

+31
-17
lines changed

clang/lib/CodeGen/CGOpenMPRuntime.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,22 +2000,29 @@ void CGOpenMPRuntime::emitCriticalRegion(CodeGenFunction &CGF,
20002000
// Prepare arguments and build a call to __kmpc_critical
20012001
if (!CGF.HaveInsertPoint())
20022002
return;
2003+
llvm::FunctionCallee RuntimeFcn = OMPBuilder.getOrCreateRuntimeFunction(
2004+
CGM.getModule(),
2005+
Hint ? OMPRTL___kmpc_critical_with_hint : OMPRTL___kmpc_critical);
2006+
llvm::Value *LockVar = getCriticalRegionLock(CriticalName);
2007+
unsigned LockVarArgIdx = 2;
2008+
if (cast<llvm::GlobalVariable>(LockVar)->getAddressSpace() !=
2009+
RuntimeFcn.getFunctionType()
2010+
->getParamType(LockVarArgIdx)
2011+
->getPointerAddressSpace())
2012+
LockVar = CGF.Builder.CreateAddrSpaceCast(
2013+
LockVar, RuntimeFcn.getFunctionType()->getParamType(LockVarArgIdx));
20032014
llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
2004-
getCriticalRegionLock(CriticalName)};
2015+
LockVar};
20052016
llvm::SmallVector<llvm::Value *, 4> EnterArgs(std::begin(Args),
20062017
std::end(Args));
20072018
if (Hint) {
20082019
EnterArgs.push_back(CGF.Builder.CreateIntCast(
20092020
CGF.EmitScalarExpr(Hint), CGM.Int32Ty, /*isSigned=*/false));
20102021
}
2011-
CommonActionTy Action(
2012-
OMPBuilder.getOrCreateRuntimeFunction(
2013-
CGM.getModule(),
2014-
Hint ? OMPRTL___kmpc_critical_with_hint : OMPRTL___kmpc_critical),
2015-
EnterArgs,
2016-
OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(),
2017-
OMPRTL___kmpc_end_critical),
2018-
Args);
2022+
CommonActionTy Action(RuntimeFcn, EnterArgs,
2023+
OMPBuilder.getOrCreateRuntimeFunction(
2024+
CGM.getModule(), OMPRTL___kmpc_end_critical),
2025+
Args);
20192026
CriticalOpGen.setAction(Action);
20202027
emitInlinedDirective(CGF, OMPD_critical, CriticalOpGen);
20212028
}

clang/test/OpenMP/force-usm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ int main(void) {
4646
// CHECK-USM-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]]
4747
// CHECK-USM: user_code.entry:
4848
// CHECK-USM-NEXT: store i32 1, ptr [[TMP0]], align 4
49-
// CHECK-USM-NEXT: [[TMP2:%.*]] = load ptr, ptr @pGI_decl_tgt_ref_ptr, align 8
49+
// CHECK-USM-NEXT: [[TMP2:%.*]] = load ptr, ptr addrspace(1) @pGI_decl_tgt_ref_ptr, align 8
5050
// CHECK-USM-NEXT: [[TMP3:%.*]] = load ptr, ptr [[TMP2]], align 8
5151
// CHECK-USM-NEXT: store i32 2, ptr [[TMP3]], align 4
5252
// CHECK-USM-NEXT: call void @__kmpc_target_deinit()

clang/test/OpenMP/spirv_target_codegen_basic.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,18 @@
66
// CHECK: @__omp_offloading_{{.*}}_dynamic_environment = weak_odr protected addrspace(1) global %struct.DynamicEnvironmentTy zeroinitializer
77
// CHECK: @__omp_offloading_{{.*}}_kernel_environment = weak_odr protected addrspace(1) constant %struct.KernelEnvironmentTy
88

9+
// CHECK: @"_gomp_critical_user_$var" = common addrspace(1) global [8 x i32] zeroinitializer, align 8
10+
911
// CHECK: define weak_odr protected spir_kernel void @__omp_offloading_{{.*}}
1012

13+
// 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 addrspace(1) @"_gomp_critical_user_$var" to ptr addrspace(4)))
14+
// 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 addrspace(1) @"_gomp_critical_user_$var" to ptr addrspace(4)))
15+
1116
int main() {
1217
int ret = 0;
1318
#pragma omp target
1419
for(int i = 0; i < 5; i++)
20+
#pragma omp critical
1521
ret++;
1622
return ret;
1723
}

llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3654,7 +3654,7 @@ class OpenMPIRBuilder {
36543654
/// \param Name Name of the variable.
36553655
LLVM_ABI GlobalVariable *
36563656
getOrCreateInternalVariable(Type *Ty, const StringRef &Name,
3657-
unsigned AddressSpace = 0);
3657+
std::optional<unsigned> AddressSpace = {});
36583658
};
36593659

36603660
/// Class to represented the control flow structure of an OpenMP canonical loop.

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8460,9 +8460,8 @@ OpenMPIRBuilder::createPlatformSpecificName(ArrayRef<StringRef> Parts) const {
84608460
Config.separator());
84618461
}
84628462

8463-
GlobalVariable *
8464-
OpenMPIRBuilder::getOrCreateInternalVariable(Type *Ty, const StringRef &Name,
8465-
unsigned AddressSpace) {
8463+
GlobalVariable *OpenMPIRBuilder::getOrCreateInternalVariable(
8464+
Type *Ty, const StringRef &Name, std::optional<unsigned> AddressSpace) {
84668465
auto &Elem = *InternalVars.try_emplace(Name, nullptr).first;
84678466
if (Elem.second) {
84688467
assert(Elem.second->getValueType() == Ty &&
@@ -8472,16 +8471,18 @@ OpenMPIRBuilder::getOrCreateInternalVariable(Type *Ty, const StringRef &Name,
84728471
// variable for possibly changing that to internal or private, or maybe
84738472
// create different versions of the function for different OMP internal
84748473
// variables.
8474+
const DataLayout &DL = M.getDataLayout();
8475+
unsigned AddressSpaceVal =
8476+
AddressSpace ? *AddressSpace : DL.getDefaultGlobalsAddressSpace();
84758477
auto Linkage = this->M.getTargetTriple().getArch() == Triple::wasm32
84768478
? GlobalValue::InternalLinkage
84778479
: GlobalValue::CommonLinkage;
84788480
auto *GV = new GlobalVariable(M, Ty, /*IsConstant=*/false, Linkage,
84798481
Constant::getNullValue(Ty), Elem.first(),
84808482
/*InsertBefore=*/nullptr,
8481-
GlobalValue::NotThreadLocal, AddressSpace);
8482-
const DataLayout &DL = M.getDataLayout();
8483+
GlobalValue::NotThreadLocal, AddressSpaceVal);
84838484
const llvm::Align TypeAlign = DL.getABITypeAlign(Ty);
8484-
const llvm::Align PtrAlign = DL.getPointerABIAlignment(AddressSpace);
8485+
const llvm::Align PtrAlign = DL.getPointerABIAlignment(AddressSpaceVal);
84858486
GV->setAlignment(std::max(TypeAlign, PtrAlign));
84868487
Elem.second = GV;
84878488
}

0 commit comments

Comments
 (0)