Skip to content

Commit 826461b

Browse files
committed
Fix the llvmir translation by getting valid type from global
1 parent 9811508 commit 826461b

2 files changed

Lines changed: 43 additions & 25 deletions

File tree

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2285,12 +2285,15 @@ def GroupprivateOp : OpenMP_Op<"groupprivate",
22852285
each group having its own copy.
22862286

22872287
This operation takes in the address of a symbol that represents the original
2288-
variable, optional DeviceTypeAttr and returns the address of its groupprivate copy.
2289-
All occurrences of groupprivate variables in a parallel region should
2290-
use the groupprivate copy returned by this operation.
2288+
variable and returns the address of its groupprivate copy. The symbol must
2289+
refer to a global variable so that type information can be obtained from it.
22912290

22922291
The `sym_addr` refers to the address of the symbol, which is a pointer to
2293-
the original variable.
2292+
the original variable. It must be obtained via `llvm.mlir.addressof` from
2293+
a global variable.
2294+
2295+
The optional `device_type` attribute specifies where the groupprivate
2296+
storage should be allocated (host, nohost, or any).
22942297
}];
22952298

22962299
let arguments = (ins

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7112,7 +7112,7 @@ convertOmpGroupprivate(Operation &opInst, llvm::IRBuilderBase &builder,
71127112
bool isTargetDevice = ompBuilder->Config.isTargetDevice();
71137113
auto deviceType = groupprivateOp.getDeviceType();
71147114

7115-
// skip allocation based on device_type
7115+
// Skip allocation based on device_type
71167116
bool shouldAllocate = true;
71177117
if (deviceType.has_value()) {
71187118
switch (*deviceType) {
@@ -7132,44 +7132,59 @@ convertOmpGroupprivate(Operation &opInst, llvm::IRBuilderBase &builder,
71327132
}
71337133

71347134
Value symAddr = groupprivateOp.getSymAddr();
7135-
Operation *symOp = symAddr.getDefiningOp();
7135+
llvm::Value *symValue = moduleTranslation.lookupValue(symAddr);
7136+
llvm::Value *resultPtr;
71367137

7137-
LLVM::GlobalOp global =
7138-
getGlobalFromSymbol(symOp, moduleTranslation, &opInst);
7139-
if (!global)
7140-
return failure();
7138+
// Get the element type and variable name from the global.
7139+
// Groupprivate requires sym_addr to come from a global variable.
7140+
llvm::Type *varType = nullptr;
7141+
std::string varName = "omp.groupprivate";
7142+
7143+
if (Operation *symOp = symAddr.getDefiningOp()) {
7144+
if (LLVM::GlobalOp global =
7145+
getGlobalFromSymbol(symOp, moduleTranslation, nullptr)) {
7146+
// Get type from the global
7147+
varType = moduleTranslation.convertType(global.getType());
7148+
// Get name from the global
7149+
if (llvm::GlobalValue *globalValue =
7150+
moduleTranslation.lookupGlobal(global)) {
7151+
varName = globalValue->getName().str();
7152+
}
7153+
}
7154+
}
71417155

7142-
llvm::GlobalValue *globalValue = moduleTranslation.lookupGlobal(global);
7143-
llvm::Value *resultPtr;
7156+
if (!varType) {
7157+
return opInst.emitError()
7158+
<< "Groupprivate requires sym_addr to reference a global variable";
7159+
}
71447160

71457161
if (shouldAllocate) {
71467162
if (isTargetDevice) {
7147-
// Get the size of the variable
7148-
llvm::Type *varType = globalValue->getValueType();
71497163
llvm::Module *llvmModule = moduleTranslation.getLLVMModule();
7150-
// Create a llvm global variable in shared memory
71517164
llvm::Triple targetTriple = llvm::Triple(llvmModule->getTargetTriple());
71527165
if (targetTriple.isAMDGCN() || targetTriple.isNVPTX()) {
7153-
// Shared address space is 3 for amdgpu and nvptx targets.
7166+
// Shared address space is 3 for AMDGPU and NVPTX targets.
71547167
unsigned sharedAddressSpace = 3;
71557168
llvm::GlobalVariable *sharedVar = new llvm::GlobalVariable(
7156-
*llvmModule, varType, false, llvm::GlobalValue::InternalLinkage,
7157-
llvm::PoisonValue::get(varType), globalValue->getName(), nullptr,
7158-
llvm::GlobalValue::NotThreadLocal, sharedAddressSpace, false);
7169+
*llvmModule, varType, /*isConstant=*/false,
7170+
llvm::GlobalValue::InternalLinkage, llvm::PoisonValue::get(varType),
7171+
varName, /*InsertBefore=*/nullptr,
7172+
llvm::GlobalValue::NotThreadLocal, sharedAddressSpace,
7173+
/*isExternallyInitialized=*/false);
71597174
resultPtr = sharedVar;
71607175
} else {
71617176
return opInst.emitError()
71627177
<< "Groupprivate operation is not supported for this target: "
71637178
<< targetTriple.str();
71647179
}
71657180
} else {
7166-
// Use original global address when allocating on host device.
7181+
// Use original address when allocating on host device.
71677182
// TODO: Add support for allocating group-private storage on host device.
7168-
resultPtr = globalValue;
7183+
resultPtr = symValue;
71697184
}
71707185
} else {
7171-
// Use original global address when not allocating group-private storage.
7172-
resultPtr = globalValue;
7186+
// Use original address when not allocating group-private storage.
7187+
resultPtr = symValue;
71737188
}
71747189

71757190
moduleTranslation.mapValue(opInst.getResult(0), resultPtr);
@@ -7184,8 +7199,8 @@ LogicalResult OpenMPDialectLLVMIRTranslationInterface::convertOperation(
71847199
llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
71857200

71867201
if (ompBuilder->Config.isTargetDevice() &&
7187-
!isa<omp::TargetOp, omp::MapInfoOp, omp::TerminatorOp, omp::YieldOp>(
7188-
op) &&
7202+
!isa<omp::TargetOp, omp::MapInfoOp, omp::TerminatorOp, omp::YieldOp,
7203+
omp::GroupprivateOp>(op) &&
71897204
isHostDeviceOp(op))
71907205
return op->emitOpError() << "unsupported host op found in device";
71917206

0 commit comments

Comments
 (0)