[Mlir-commits] [mlir] 1e92e25 - [MLIR][OpenMP] Added MLIR translation support for use_device clauses
Akash Banerjee
llvmlistbot at llvm.org
Fri Aug 4 07:38:58 PDT 2023
Author: Akash Banerjee
Date: 2023-08-04T15:38:50+01:00
New Revision: 1e92e25cb4a96d4997028632bb577c1698694891
URL: https://github.com/llvm/llvm-project/commit/1e92e25cb4a96d4997028632bb577c1698694891
DIFF: https://github.com/llvm/llvm-project/commit/1e92e25cb4a96d4997028632bb577c1698694891.diff
LOG: [MLIR][OpenMP] Added MLIR translation support for use_device clauses
Added MLIR support for translating use_device_ptr and use_device_addr clauses for LLVMIR lowering.
- use_device_ptr: The mapped variables marked with use_device_ptr are accessed through a copy of the base pointer mappers. The mapper is copied onto a new temporary pointer variable.
- use_device_addr: The mapped variables marked with use_device_addr are accessed directly through the base pointer mappers.
- If mapping information is not provided explicitly then default map_type of alloc/release is assumed and the map_size is set to 0.
Depends on D152554
Reviewed By: kiranchandramohan, raghavendhra
Differential Revision: https://reviews.llvm.org/D146648
Added:
Modified:
llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
mlir/test/Target/LLVMIR/omptarget-llvm.mlir
Removed:
################################################################################
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 988b0df9eaf1cc..1694df8f482e67 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -4848,14 +4848,12 @@ void OpenMPIRBuilder::emitOffloadingArrays(
Builder.restoreIP(AllocaIP);
Info.DevicePtrInfoMap[BPVal] = {BP, Builder.CreateAlloca(PtrTy)};
Builder.restoreIP(CodeGenIP);
- assert(DeviceAddrCB &&
- "DeviceAddrCB missing for DevicePtr code generation");
- DeviceAddrCB(I, Info.DevicePtrInfoMap[BPVal].second);
+ if (DeviceAddrCB)
+ DeviceAddrCB(I, Info.DevicePtrInfoMap[BPVal].second);
} else if (CombinedInfo.DevicePointers[I] == DeviceInfoTy::Address) {
Info.DevicePtrInfoMap[BPVal] = {BP, BP};
- assert(DeviceAddrCB &&
- "DeviceAddrCB missing for DevicePtr code generation");
- DeviceAddrCB(I, BP);
+ if (DeviceAddrCB)
+ DeviceAddrCB(I, BP);
}
}
diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
index 4f795ba9cf7a2e..51af5eb392f5ae 100644
--- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
+++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
@@ -4894,6 +4894,8 @@ TEST_F(OpenMPIRBuilderTest, TargetEnterData) {
CombinedInfo.BasePointers.emplace_back(Val1);
CombinedInfo.Pointers.emplace_back(Val1);
+ CombinedInfo.DevicePointers.emplace_back(
+ llvm::OpenMPIRBuilder::DeviceInfoTy::None);
CombinedInfo.Sizes.emplace_back(Builder.getInt64(4));
CombinedInfo.Types.emplace_back(llvm::omp::OpenMPOffloadMappingFlags(1));
uint32_t temp;
@@ -4951,6 +4953,8 @@ TEST_F(OpenMPIRBuilderTest, TargetExitData) {
CombinedInfo.BasePointers.emplace_back(Val1);
CombinedInfo.Pointers.emplace_back(Val1);
+ CombinedInfo.DevicePointers.emplace_back(
+ llvm::OpenMPIRBuilder::DeviceInfoTy::None);
CombinedInfo.Sizes.emplace_back(Builder.getInt64(4));
CombinedInfo.Types.emplace_back(llvm::omp::OpenMPOffloadMappingFlags(2));
uint32_t temp;
@@ -4996,36 +5000,63 @@ TEST_F(OpenMPIRBuilderTest, TargetDataRegion) {
Builder.CreateAlloca(Builder.getInt32Ty(), Builder.getInt64(1));
ASSERT_NE(Val1, nullptr);
+ AllocaInst *Val2 = Builder.CreateAlloca(Builder.getPtrTy());
+ ASSERT_NE(Val2, nullptr);
+
+ AllocaInst *Val3 = Builder.CreateAlloca(Builder.getPtrTy());
+ ASSERT_NE(Val3, nullptr);
+
IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
F->getEntryBlock().getFirstInsertionPt());
+ using DeviceInfoTy = llvm::OpenMPIRBuilder::DeviceInfoTy;
llvm::OpenMPIRBuilder::MapInfosTy CombinedInfo;
using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
auto GenMapInfoCB =
[&](InsertPointTy codeGenIP) -> llvm::OpenMPIRBuilder::MapInfosTy & {
// Get map clause information.
Builder.restoreIP(codeGenIP);
+ uint32_t temp;
CombinedInfo.BasePointers.emplace_back(Val1);
CombinedInfo.Pointers.emplace_back(Val1);
+ CombinedInfo.DevicePointers.emplace_back(DeviceInfoTy::None);
CombinedInfo.Sizes.emplace_back(Builder.getInt64(4));
CombinedInfo.Types.emplace_back(llvm::omp::OpenMPOffloadMappingFlags(3));
- uint32_t temp;
+ CombinedInfo.Names.emplace_back(
+ OMPBuilder.getOrCreateSrcLocStr("unknown", temp));
+
+ CombinedInfo.BasePointers.emplace_back(Val2);
+ CombinedInfo.Pointers.emplace_back(Val2);
+ CombinedInfo.DevicePointers.emplace_back(DeviceInfoTy::Pointer);
+ CombinedInfo.Sizes.emplace_back(Builder.getInt64(8));
+ CombinedInfo.Types.emplace_back(llvm::omp::OpenMPOffloadMappingFlags(67));
+ CombinedInfo.Names.emplace_back(
+ OMPBuilder.getOrCreateSrcLocStr("unknown", temp));
+
+ CombinedInfo.BasePointers.emplace_back(Val3);
+ CombinedInfo.Pointers.emplace_back(Val3);
+ CombinedInfo.DevicePointers.emplace_back(DeviceInfoTy::Address);
+ CombinedInfo.Sizes.emplace_back(Builder.getInt64(8));
+ CombinedInfo.Types.emplace_back(llvm::omp::OpenMPOffloadMappingFlags(67));
CombinedInfo.Names.emplace_back(
OMPBuilder.getOrCreateSrcLocStr("unknown", temp));
return CombinedInfo;
};
llvm::OpenMPIRBuilder::TargetDataInfo Info(
- /*RequiresDevicePointerInfo=*/false,
+ /*RequiresDevicePointerInfo=*/true,
/*SeparateBeginEndCalls=*/true);
OMPBuilder.Config.setIsGPU(true);
- auto BodyCB = [&](InsertPointTy CodeGenIP, int BodyGenType) {
- if (BodyGenType == 3) {
+ using BodyGenTy = llvm::OpenMPIRBuilder::BodyGenTy;
+ auto BodyCB = [&](InsertPointTy CodeGenIP, BodyGenTy BodyGenType) {
+ if (BodyGenType == BodyGenTy::Priv) {
+ EXPECT_EQ(Info.DevicePtrInfoMap.size(), 2u);
Builder.restoreIP(CodeGenIP);
- CallInst *TargetDataCall = dyn_cast<CallInst>(&BB->back());
+ CallInst *TargetDataCall =
+ dyn_cast<CallInst>(BB->back().getPrevNode()->getPrevNode());
EXPECT_NE(TargetDataCall, nullptr);
EXPECT_EQ(TargetDataCall->arg_size(), 9U);
EXPECT_EQ(TargetDataCall->getCalledFunction()->getName(),
@@ -5033,7 +5064,15 @@ TEST_F(OpenMPIRBuilderTest, TargetDataRegion) {
EXPECT_TRUE(TargetDataCall->getOperand(1)->getType()->isIntegerTy(64));
EXPECT_TRUE(TargetDataCall->getOperand(2)->getType()->isIntegerTy(32));
EXPECT_TRUE(TargetDataCall->getOperand(8)->getType()->isPointerTy());
- Builder.restoreIP(CodeGenIP);
+
+ LoadInst *LI = dyn_cast<LoadInst>(BB->back().getPrevNode());
+ EXPECT_NE(LI, nullptr);
+ StoreInst *SI = dyn_cast<StoreInst>(&BB->back());
+ EXPECT_NE(SI, nullptr);
+ EXPECT_EQ(SI->getValueOperand(), LI);
+ EXPECT_EQ(SI->getPointerOperand(), Info.DevicePtrInfoMap[Val2].second);
+ EXPECT_TRUE(isa<AllocaInst>(Info.DevicePtrInfoMap[Val2].second));
+ EXPECT_TRUE(isa<GetElementPtrInst>(Info.DevicePtrInfoMap[Val3].second));
Builder.CreateStore(Builder.getInt32(99), Val1);
}
return Builder.saveIP();
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 42545f276298c1..97f1362f470c7f 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -1367,44 +1367,92 @@ convertOmpThreadprivate(Operation &opInst, llvm::IRBuilderBase &builder,
return success();
}
-int64_t getSizeInBytes(DataLayout &DL, const mlir::Type &type) {
+int64_t getSizeInBytes(DataLayout &DL, const Type &type) {
if (isa<LLVM::LLVMPointerType>(type))
return DL.getTypeSize(cast<LLVM::LLVMPointerType>(type).getElementType());
return 0;
}
+// Generate all map related information and fill the combinedInfo.
static void genMapInfos(llvm::IRBuilderBase &builder,
LLVM::ModuleTranslation &moduleTranslation,
DataLayout &DL,
llvm::OpenMPIRBuilder::MapInfosTy &combinedInfo,
const SmallVector<Value> &mapOperands,
- const ArrayAttr &mapTypes) {
- // Get map clause information.
+ const ArrayAttr &mapTypes,
+ const SmallVector<Value> &devPtrOperands = {},
+ const SmallVector<Value> &devAddrOperands = {}) {
llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
+
+ auto fail = [&combinedInfo]() -> void {
+ combinedInfo.BasePointers.clear();
+ combinedInfo.Pointers.clear();
+ combinedInfo.DevicePointers.clear();
+ combinedInfo.Sizes.clear();
+ combinedInfo.Types.clear();
+ combinedInfo.Names.clear();
+ };
+
+ auto findMapInfo = [&combinedInfo](llvm::Value *val, unsigned &index) {
+ index = 0;
+ for (auto basePtr : combinedInfo.BasePointers) {
+ if (basePtr == val)
+ return true;
+ index++;
+ }
+ return false;
+ };
+
unsigned index = 0;
for (const auto &mapOp : mapOperands) {
- if (!mapOp.getType().isa<LLVM::LLVMPointerType>()) {
- // TODO: Only LLVMPointerTypes are handled.
- combinedInfo.BasePointers.clear();
- combinedInfo.Pointers.clear();
- combinedInfo.Sizes.clear();
- combinedInfo.Types.clear();
- combinedInfo.Names.clear();
- return;
- }
+ // TODO: Only LLVMPointerTypes are handled.
+ if (!mapOp.getType().isa<LLVM::LLVMPointerType>())
+ return fail();
llvm::Value *mapOpValue = moduleTranslation.lookupValue(mapOp);
combinedInfo.BasePointers.emplace_back(mapOpValue);
combinedInfo.Pointers.emplace_back(mapOpValue);
+ combinedInfo.DevicePointers.emplace_back(
+ llvm::OpenMPIRBuilder::DeviceInfoTy::None);
combinedInfo.Names.emplace_back(
- mlir::LLVM::createMappingInformation(mapOp.getLoc(), *ompBuilder));
+ LLVM::createMappingInformation(mapOp.getLoc(), *ompBuilder));
combinedInfo.Types.emplace_back(llvm::omp::OpenMPOffloadMappingFlags(
- mapTypes[index].dyn_cast<mlir::IntegerAttr>().getInt()));
+ mapTypes[index].dyn_cast<IntegerAttr>().getInt()));
combinedInfo.Sizes.emplace_back(
builder.getInt64(getSizeInBytes(DL, mapOp.getType())));
index++;
}
+
+ auto addDevInfos = [&, fail](auto devOperands, auto devOpType) -> void {
+ for (const auto &devOp : devOperands) {
+ // TODO: Only LLVMPointerTypes are handled.
+ if (!devOp.getType().template isa<LLVM::LLVMPointerType>())
+ return fail();
+
+ llvm::Value *mapOpValue = moduleTranslation.lookupValue(devOp);
+
+ // Check if map info is already present for this entry.
+ unsigned infoIndex;
+ if (findMapInfo(mapOpValue, infoIndex)) {
+ combinedInfo.Types[infoIndex] |=
+ llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM;
+ combinedInfo.DevicePointers[infoIndex] = devOpType;
+ } else {
+ combinedInfo.BasePointers.emplace_back(mapOpValue);
+ combinedInfo.Pointers.emplace_back(mapOpValue);
+ combinedInfo.DevicePointers.emplace_back(devOpType);
+ combinedInfo.Names.emplace_back(
+ LLVM::createMappingInformation(devOp.getLoc(), *ompBuilder));
+ combinedInfo.Types.emplace_back(
+ llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM);
+ combinedInfo.Sizes.emplace_back(builder.getInt64(0));
+ }
+ }
+ };
+
+ addDevInfos(devPtrOperands, llvm::OpenMPIRBuilder::DeviceInfoTy::Pointer);
+ addDevInfos(devAddrOperands, llvm::OpenMPIRBuilder::DeviceInfoTy::Address);
}
static LogicalResult
@@ -1413,6 +1461,8 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
llvm::Value *ifCond = nullptr;
int64_t deviceID = llvm::omp::OMP_DEVICEID_UNDEF;
SmallVector<Value> mapOperands;
+ SmallVector<Value> useDevPtrOperands;
+ SmallVector<Value> useDevAddrOperands;
ArrayAttr mapTypes;
llvm::omp::RuntimeFunction RTLFn;
DataLayout DL = DataLayout(op->getParentOfType<ModuleOp>());
@@ -1422,23 +1472,20 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
LogicalResult result =
llvm::TypeSwitch<Operation *, LogicalResult>(op)
.Case([&](omp::DataOp dataOp) {
- if (!dataOp.getUseDeviceAddr().empty() ||
- !dataOp.getUseDevicePtr().empty())
- return failure();
-
if (auto ifExprVar = dataOp.getIfExpr())
ifCond = moduleTranslation.lookupValue(ifExprVar);
if (auto devId = dataOp.getDevice())
- if (auto constOp = mlir::dyn_cast<mlir::LLVM::ConstantOp>(
- devId.getDefiningOp()))
- if (auto intAttr =
- dyn_cast<mlir::IntegerAttr>(constOp.getValue()))
+ if (auto constOp =
+ dyn_cast<LLVM::ConstantOp>(devId.getDefiningOp()))
+ if (auto intAttr = dyn_cast<IntegerAttr>(constOp.getValue()))
deviceID = intAttr.getInt();
mapOperands = dataOp.getMapOperands();
if (dataOp.getMapTypes())
mapTypes = dataOp.getMapTypes().value();
+ useDevPtrOperands = dataOp.getUseDevicePtr();
+ useDevAddrOperands = dataOp.getUseDeviceAddr();
return success();
})
.Case([&](omp::EnterDataOp enterDataOp) {
@@ -1449,10 +1496,9 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
ifCond = moduleTranslation.lookupValue(ifExprVar);
if (auto devId = enterDataOp.getDevice())
- if (auto constOp = mlir::dyn_cast<mlir::LLVM::ConstantOp>(
- devId.getDefiningOp()))
- if (auto intAttr =
- dyn_cast<mlir::IntegerAttr>(constOp.getValue()))
+ if (auto constOp =
+ dyn_cast<LLVM::ConstantOp>(devId.getDefiningOp()))
+ if (auto intAttr = dyn_cast<IntegerAttr>(constOp.getValue()))
deviceID = intAttr.getInt();
RTLFn = llvm::omp::OMPRTL___tgt_target_data_begin_mapper;
mapOperands = enterDataOp.getMapOperands();
@@ -1467,10 +1513,9 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
ifCond = moduleTranslation.lookupValue(ifExprVar);
if (auto devId = exitDataOp.getDevice())
- if (auto constOp = mlir::dyn_cast<mlir::LLVM::ConstantOp>(
- devId.getDefiningOp()))
- if (auto intAttr =
- dyn_cast<mlir::IntegerAttr>(constOp.getValue()))
+ if (auto constOp =
+ dyn_cast<LLVM::ConstantOp>(devId.getDefiningOp()))
+ if (auto intAttr = dyn_cast<IntegerAttr>(constOp.getValue()))
deviceID = intAttr.getInt();
RTLFn = llvm::omp::OMPRTL___tgt_target_data_end_mapper;
@@ -1493,26 +1538,61 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
auto genMapInfoCB =
[&](InsertPointTy codeGenIP) -> llvm::OpenMPIRBuilder::MapInfosTy & {
builder.restoreIP(codeGenIP);
- genMapInfos(builder, moduleTranslation, DL, combinedInfo, mapOperands,
- mapTypes);
+ if (auto DataOp = dyn_cast<omp::DataOp>(op)) {
+ genMapInfos(builder, moduleTranslation, DL, combinedInfo, mapOperands,
+ mapTypes, useDevPtrOperands, useDevAddrOperands);
+ } else {
+ genMapInfos(builder, moduleTranslation, DL, combinedInfo, mapOperands,
+ mapTypes);
+ }
return combinedInfo;
};
- LogicalResult bodyGenStatus = success();
+ llvm::OpenMPIRBuilder::TargetDataInfo info(/*RequiresDevicePointerInfo=*/true,
+ /*SeparateBeginEndCalls=*/true);
+
using BodyGenTy = llvm::OpenMPIRBuilder::BodyGenTy;
+ LogicalResult bodyGenStatus = success();
auto bodyGenCB = [&](InsertPointTy codeGenIP, BodyGenTy bodyGenType) {
+ assert(isa<omp::DataOp>(op) && "BodyGen requested for non DataOp");
+ Region ®ion = cast<omp::DataOp>(op).getRegion();
switch (bodyGenType) {
case BodyGenTy::Priv:
+ // Check if any device ptr/addr info is available
+ if (!info.DevicePtrInfoMap.empty()) {
+ builder.restoreIP(codeGenIP);
+ unsigned argIndex = 0;
+ for (auto &devPtrOp : useDevPtrOperands) {
+ llvm::Value *mapOpValue = moduleTranslation.lookupValue(devPtrOp);
+ const auto &arg = region.front().getArgument(argIndex);
+ moduleTranslation.mapValue(arg,
+ info.DevicePtrInfoMap[mapOpValue].second);
+ argIndex++;
+ }
+
+ for (auto &devAddrOp : useDevAddrOperands) {
+ llvm::Value *mapOpValue = moduleTranslation.lookupValue(devAddrOp);
+ const auto &arg = region.front().getArgument(argIndex);
+ auto *LI = builder.CreateLoad(
+ builder.getPtrTy(), info.DevicePtrInfoMap[mapOpValue].second);
+ moduleTranslation.mapValue(arg, LI);
+ argIndex++;
+ }
+
+ bodyGenStatus = inlineConvertOmpRegions(region, "omp.data.region",
+ builder, moduleTranslation);
+ }
break;
case BodyGenTy::DupNoPriv:
break;
- case BodyGenTy::NoPriv: {
- // DataOp has only one region associated with it.
- auto ®ion = cast<omp::DataOp>(op).getRegion();
- builder.restoreIP(codeGenIP);
- bodyGenStatus = inlineConvertOmpRegions(region, "omp.data.region",
- builder, moduleTranslation);
- }
+ case BodyGenTy::NoPriv:
+ // If device info is available then region has already been generated
+ if (info.DevicePtrInfoMap.empty()) {
+ builder.restoreIP(codeGenIP);
+ bodyGenStatus = inlineConvertOmpRegions(region, "omp.data.region",
+ builder, moduleTranslation);
+ }
+ break;
}
return builder.saveIP();
};
@@ -1520,11 +1600,6 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder);
llvm::OpenMPIRBuilder::InsertPointTy allocaIP =
findAllocaInsertPoint(builder, moduleTranslation);
-
- // TODO: Add support for DevicePointerInfo
- llvm::OpenMPIRBuilder::TargetDataInfo info(
- /*RequiresDevicePointerInfo=*/false,
- /*SeparateBeginEndCalls=*/true);
if (isa<omp::DataOp>(op)) {
builder.restoreIP(ompBuilder->createTargetData(
ompLoc, allocaIP, builder.saveIP(), builder.getInt64(deviceID), ifCond,
@@ -1693,7 +1768,7 @@ convertDeclareTargetAttr(Operation *op,
// lowering while removing functions at the current time.
if (!isDeviceCompilation)
return success();
-
+
omp::DeclareTargetDeviceType declareType =
declareTargetAttr.getDeviceType().getValue();
diff --git a/mlir/test/Target/LLVMIR/omptarget-llvm.mlir b/mlir/test/Target/LLVMIR/omptarget-llvm.mlir
index 1573f30d5b391b..0a6dedc754857b 100644
--- a/mlir/test/Target/LLVMIR/omptarget-llvm.mlir
+++ b/mlir/test/Target/LLVMIR/omptarget-llvm.mlir
@@ -168,3 +168,239 @@ llvm.func @_QPomp_target_enter_exit(%1 : !llvm.ptr<array<1024 x i32>>, %3 : !llv
// CHECK: ret void
// -----
+
+llvm.func @_QPopenmp_target_use_dev_ptr() {
+ %0 = llvm.mlir.constant(1 : i64) : i64
+ %a = llvm.alloca %0 x !llvm.ptr<!llvm.ptr<i32>> : (i64) -> !llvm.ptr<!llvm.ptr<i32>>
+ omp.target_data map((from -> %a : !llvm.ptr<!llvm.ptr<i32>>)) use_device_ptr(%a : !llvm.ptr<!llvm.ptr<i32>>) {
+ ^bb0(%arg0: !llvm.ptr<!llvm.ptr<i32>>):
+ %1 = llvm.mlir.constant(10 : i32) : i32
+ %2 = llvm.load %arg0 : !llvm.ptr<!llvm.ptr<i32>>
+ llvm.store %1, %2 : !llvm.ptr<i32>
+ omp.terminator
+ }
+ llvm.return
+}
+
+// CHECK: @.offload_sizes = private unnamed_addr constant [1 x i64] [i64 8]
+// CHECK: @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 66]
+// CHECK-LABEL: define void @_QPopenmp_target_use_dev_ptr
+// CHECK: %[[VAL_0:.*]] = alloca [1 x ptr], align 8
+// CHECK: %[[VAL_1:.*]] = alloca [1 x ptr], align 8
+// CHECK: %[[VAL_2:.*]] = alloca [1 x ptr], align 8
+// CHECK: %[[VAL_3:.*]] = alloca ptr, align 8
+// CHECK: %[[VAL_4:.*]] = alloca ptr, i64 1, align 8
+// CHECK: br label %[[VAL_5:.*]]
+// CHECK: entry: ; preds = %[[VAL_6:.*]]
+// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: store ptr %[[VAL_4]], ptr %[[VAL_7]], align 8
+// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: store ptr %[[VAL_4]], ptr %[[VAL_8]], align 8
+// CHECK: %[[VAL_9:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_2]], i64 0, i64 0
+// CHECK: store ptr null, ptr %[[VAL_9]], align 8
+// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: %[[VAL_11:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_10]], ptr %[[VAL_11]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK: %[[VAL_12:.*]] = load ptr, ptr %[[VAL_7]], align 8
+// CHECK: store ptr %[[VAL_12]], ptr %[[VAL_3]], align 8
+// CHECK: %[[VAL_13:.*]] = load ptr, ptr %[[VAL_3]], align 8
+// CHECK: store i32 10, ptr %[[VAL_13]], align 4
+// CHECK: %[[VAL_14:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: %[[VAL_15:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_14]], ptr %[[VAL_15]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK: ret void
+
+// -----
+
+llvm.func @_QPopenmp_target_use_dev_addr() {
+ %0 = llvm.mlir.constant(1 : i64) : i64
+ %a = llvm.alloca %0 x !llvm.ptr<!llvm.ptr<i32>> : (i64) -> !llvm.ptr<!llvm.ptr<i32>>
+ omp.target_data map((from -> %a : !llvm.ptr<!llvm.ptr<i32>>)) use_device_addr(%a : !llvm.ptr<!llvm.ptr<i32>>) {
+ ^bb0(%arg0: !llvm.ptr<!llvm.ptr<i32>>):
+ %1 = llvm.mlir.constant(10 : i32) : i32
+ %2 = llvm.load %arg0 : !llvm.ptr<!llvm.ptr<i32>>
+ llvm.store %1, %2 : !llvm.ptr<i32>
+ omp.terminator
+ }
+ llvm.return
+}
+
+// CHECK: @.offload_sizes = private unnamed_addr constant [1 x i64] [i64 8]
+// CHECK: @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 66]
+// CHECK-LABEL: define void @_QPopenmp_target_use_dev_addr
+// CHECK: %[[VAL_0:.*]] = alloca [1 x ptr], align 8
+// CHECK: %[[VAL_1:.*]] = alloca [1 x ptr], align 8
+// CHECK: %[[VAL_2:.*]] = alloca [1 x ptr], align 8
+// CHECK: %[[VAL_3:.*]] = alloca ptr, i64 1, align 8
+// CHECK: br label %[[VAL_4:.*]]
+// CHECK: entry: ; preds = %[[VAL_5:.*]]
+// CHECK: %[[VAL_6:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: store ptr %[[VAL_3]], ptr %[[VAL_6]], align 8
+// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: store ptr %[[VAL_3]], ptr %[[VAL_7]], align 8
+// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_2]], i64 0, i64 0
+// CHECK: store ptr null, ptr %[[VAL_8]], align 8
+// CHECK: %[[VAL_9:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_9]], ptr %[[VAL_10]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK: %[[VAL_11:.*]] = load ptr, ptr %[[VAL_6]], align 8
+// CHECK: %[[VAL_12:.*]] = load ptr, ptr %[[VAL_11]], align 8
+// CHECK: store i32 10, ptr %[[VAL_12]], align 4
+// CHECK: %[[VAL_13:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: %[[VAL_14:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_13]], ptr %[[VAL_14]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK: ret void
+
+// -----
+
+llvm.func @_QPopenmp_target_use_dev_addr_no_ptr() {
+ %0 = llvm.mlir.constant(1 : i64) : i64
+ %a = llvm.alloca %0 x !llvm.ptr<i32> : (i64) -> !llvm.ptr<i32>
+ omp.target_data map((tofrom -> %a : !llvm.ptr<i32>)) use_device_addr(%a : !llvm.ptr<i32>) {
+ ^bb0(%arg0: !llvm.ptr<i32>):
+ %1 = llvm.mlir.constant(10 : i32) : i32
+ llvm.store %1, %arg0 : !llvm.ptr<i32>
+ omp.terminator
+ }
+ llvm.return
+}
+
+// CHECK: @.offload_sizes = private unnamed_addr constant [1 x i64] [i64 4]
+// CHECK: @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 67]
+// CHECK-LABEL: define void @_QPopenmp_target_use_dev_addr_no_ptr
+// CHECK: %[[VAL_0:.*]] = alloca [1 x ptr], align 8
+// CHECK: %[[VAL_1:.*]] = alloca [1 x ptr], align 8
+// CHECK: %[[VAL_2:.*]] = alloca [1 x ptr], align 8
+// CHECK: %[[VAL_3:.*]] = alloca i32, i64 1, align 4
+// CHECK: br label %[[VAL_4:.*]]
+// CHECK: entry: ; preds = %[[VAL_5:.*]]
+// CHECK: %[[VAL_6:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: store ptr %[[VAL_3]], ptr %[[VAL_6]], align 8
+// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: store ptr %[[VAL_3]], ptr %[[VAL_7]], align 8
+// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_2]], i64 0, i64 0
+// CHECK: store ptr null, ptr %[[VAL_8]], align 8
+// CHECK: %[[VAL_9:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_9]], ptr %[[VAL_10]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK: %[[VAL_11:.*]] = load ptr, ptr %[[VAL_6]], align 8
+// CHECK: store i32 10, ptr %[[VAL_11]], align 4
+// CHECK: %[[VAL_12:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: %[[VAL_13:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_12]], ptr %[[VAL_13]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK: ret void
+
+// -----
+
+llvm.func @_QPopenmp_target_use_dev_addr_nomap() {
+ %0 = llvm.mlir.constant(1 : i64) : i64
+ %a = llvm.alloca %0 x !llvm.ptr<!llvm.ptr<i32>> : (i64) -> !llvm.ptr<!llvm.ptr<i32>>
+ %1 = llvm.mlir.constant(1 : i64) : i64
+ %b = llvm.alloca %0 x !llvm.ptr<!llvm.ptr<i32>> : (i64) -> !llvm.ptr<!llvm.ptr<i32>>
+ omp.target_data map((from -> %b : !llvm.ptr<!llvm.ptr<i32>>)) use_device_addr(%a : !llvm.ptr<!llvm.ptr<i32>>) {
+ ^bb0(%arg0: !llvm.ptr<!llvm.ptr<i32>>):
+ %2 = llvm.mlir.constant(10 : i32) : i32
+ %3 = llvm.load %arg0 : !llvm.ptr<!llvm.ptr<i32>>
+ llvm.store %2, %3 : !llvm.ptr<i32>
+ %4 = llvm.mlir.constant(20 : i32) : i32
+ %5 = llvm.load %b : !llvm.ptr<!llvm.ptr<i32>>
+ llvm.store %4, %5 : !llvm.ptr<i32>
+ omp.terminator
+ }
+ llvm.return
+}
+
+// CHECK: @.offload_sizes = private unnamed_addr constant [2 x i64] [i64 8, i64 0]
+// CHECK: @.offload_maptypes = private unnamed_addr constant [2 x i64] [i64 2, i64 64]
+// CHECK-LABEL: define void @_QPopenmp_target_use_dev_addr_nomap
+// CHECK: %[[VAL_0:.*]] = alloca [2 x ptr], align 8
+// CHECK: %[[VAL_1:.*]] = alloca [2 x ptr], align 8
+// CHECK: %[[VAL_2:.*]] = alloca [2 x ptr], align 8
+// CHECK: %[[VAL_3:.*]] = alloca ptr, i64 1, align 8
+// CHECK: %[[VAL_4:.*]] = alloca ptr, i64 1, align 8
+// CHECK: br label %[[VAL_5:.*]]
+// CHECK: entry: ; preds = %[[VAL_6:.*]]
+// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: store ptr %[[VAL_4]], ptr %[[VAL_7]], align 8
+// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: store ptr %[[VAL_4]], ptr %[[VAL_8]], align 8
+// CHECK: %[[VAL_9:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_2]], i64 0, i64 0
+// CHECK: store ptr null, ptr %[[VAL_9]], align 8
+// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 1
+// CHECK: store ptr %[[VAL_3]], ptr %[[VAL_10]], align 8
+// CHECK: %[[VAL_11:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 1
+// CHECK: store ptr %[[VAL_3]], ptr %[[VAL_11]], align 8
+// CHECK: %[[VAL_12:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_2]], i64 0, i64 1
+// CHECK: store ptr null, ptr %[[VAL_12]], align 8
+// CHECK: %[[VAL_13:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: %[[VAL_14:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: call void @__tgt_target_data_begin_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_13]], ptr %[[VAL_14]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK: %[[VAL_15:.*]] = load ptr, ptr %[[VAL_10]], align 8
+// CHECK: %[[VAL_16:.*]] = load ptr, ptr %[[VAL_15]], align 8
+// CHECK: store i32 10, ptr %[[VAL_16]], align 4
+// CHECK: %[[VAL_17:.*]] = load ptr, ptr %[[VAL_4]], align 8
+// CHECK: store i32 20, ptr %[[VAL_17]], align 4
+// CHECK: %[[VAL_18:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: %[[VAL_19:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: call void @__tgt_target_data_end_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_18]], ptr %[[VAL_19]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK: ret void
+
+// -----
+
+llvm.func @_QPopenmp_target_use_dev_both() {
+ %0 = llvm.mlir.constant(1 : i64) : i64
+ %a = llvm.alloca %0 x !llvm.ptr<!llvm.ptr<i32>> : (i64) -> !llvm.ptr<!llvm.ptr<i32>>
+ %1 = llvm.mlir.constant(1 : i64) : i64
+ %b = llvm.alloca %0 x !llvm.ptr<!llvm.ptr<i32>> : (i64) -> !llvm.ptr<!llvm.ptr<i32>>
+ omp.target_data map((tofrom -> %a : !llvm.ptr<!llvm.ptr<i32>>), (tofrom -> %b : !llvm.ptr<!llvm.ptr<i32>>)) use_device_ptr(%a : !llvm.ptr<!llvm.ptr<i32>>) use_device_addr(%b : !llvm.ptr<!llvm.ptr<i32>>) {
+ ^bb0(%arg0: !llvm.ptr<!llvm.ptr<i32>>, %arg1: !llvm.ptr<!llvm.ptr<i32>>):
+ %2 = llvm.mlir.constant(10 : i32) : i32
+ %3 = llvm.load %arg0 : !llvm.ptr<!llvm.ptr<i32>>
+ llvm.store %2, %3 : !llvm.ptr<i32>
+ %4 = llvm.mlir.constant(20 : i32) : i32
+ %5 = llvm.load %arg1 : !llvm.ptr<!llvm.ptr<i32>>
+ llvm.store %4, %5 : !llvm.ptr<i32>
+ omp.terminator
+ }
+ llvm.return
+}
+
+// CHECK: @.offload_sizes = private unnamed_addr constant [2 x i64] [i64 8, i64 8]
+// CHECK: @.offload_maptypes = private unnamed_addr constant [2 x i64] [i64 67, i64 67]
+// CHECK-LABEL: define void @_QPopenmp_target_use_dev_both
+// CHECK: %[[VAL_0:.*]] = alloca [2 x ptr], align 8
+// CHECK: %[[VAL_1:.*]] = alloca [2 x ptr], align 8
+// CHECK: %[[VAL_2:.*]] = alloca [2 x ptr], align 8
+// CHECK: %[[VAL_3:.*]] = alloca ptr, align 8
+// CHECK: %[[VAL_4:.*]] = alloca ptr, i64 1, align 8
+// CHECK: %[[VAL_5:.*]] = alloca ptr, i64 1, align 8
+// CHECK: br label %[[VAL_6:.*]]
+// CHECK: entry: ; preds = %[[VAL_7:.*]]
+// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: store ptr %[[VAL_4]], ptr %[[VAL_8]], align 8
+// CHECK: %[[VAL_9:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: store ptr %[[VAL_4]], ptr %[[VAL_9]], align 8
+// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_2]], i64 0, i64 0
+// CHECK: store ptr null, ptr %[[VAL_10]], align 8
+// CHECK: %[[VAL_11:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 1
+// CHECK: store ptr %[[VAL_5]], ptr %[[VAL_11]], align 8
+// CHECK: %[[VAL_12:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 1
+// CHECK: store ptr %[[VAL_5]], ptr %[[VAL_12]], align 8
+// CHECK: %[[VAL_13:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_2]], i64 0, i64 1
+// CHECK: store ptr null, ptr %[[VAL_13]], align 8
+// CHECK: %[[VAL_14:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: %[[VAL_15:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: call void @__tgt_target_data_begin_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_14]], ptr %[[VAL_15]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK: %[[VAL_16:.*]] = load ptr, ptr %[[VAL_8]], align 8
+// CHECK: store ptr %[[VAL_16]], ptr %[[VAL_3]], align 8
+// CHECK: %[[VAL_17:.*]] = load ptr, ptr %[[VAL_11]], align 8
+// CHECK: %[[VAL_18:.*]] = load ptr, ptr %[[VAL_3]], align 8
+// CHECK: store i32 10, ptr %[[VAL_18]], align 4
+// CHECK: %[[VAL_19:.*]] = load ptr, ptr %[[VAL_17]], align 8
+// CHECK: store i32 20, ptr %[[VAL_19]], align 4
+// CHECK: %[[VAL_20:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
+// CHECK: %[[VAL_21:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
+// CHECK: call void @__tgt_target_data_end_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_20]], ptr %[[VAL_21]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
+// CHECK: ret void
+
+// -----
More information about the Mlir-commits
mailing list