Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5323,6 +5323,20 @@ convertTargetOpsInNest(Operation *op, llvm::IRBuilderBase &builder,
if (auto blockArgsIface =
dyn_cast<omp::BlockArgOpenMPOpInterface>(oper))
forwardArgs(moduleTranslation, blockArgsIface);
else {
// Here we map entry block arguments of
// non-BlockArgOpenMPOpInterface ops if they can be encountered
// inside of a function and they define any of these arguments.
if (isa<mlir::omp::AtomicUpdateOp>(oper))
for (auto [operand, arg] :
llvm::zip_equal(oper->getOperands(),
oper->getRegion(0).getArguments())) {
moduleTranslation.mapValue(
arg, builder.CreateLoad(
moduleTranslation.convertType(arg.getType()),
moduleTranslation.lookupValue(operand)));
}
}

if (auto loopNest = dyn_cast<omp::LoopNestOp>(oper)) {
assert(builder.GetInsertBlock() &&
Expand All @@ -5340,9 +5354,10 @@ convertTargetOpsInNest(Operation *op, llvm::IRBuilderBase &builder,
// translation of the OpenMP construct being converted (e.g. no
// OpenMP runtime calls will be generated). We just need this to
// prepare the kernel invocation args.
SmallVector<llvm::PHINode *> phis;
auto result = convertOmpOpRegions(
region, oper->getName().getStringRef().str() + ".fake.region",
builder, moduleTranslation);
builder, moduleTranslation, &phis);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see phis isn't used. Does passing the vector on its own cause a behavior change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, since omp.atomic.update yields values (which are not used in this context), convertOmpOpRegions asserts unless we pass a vector to collect the phis.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see, and I guess not using these PHI nodes later doesn't cause issues. Thanks for the explanation!

if (failed(handleError(result, *oper)))
return WalkResult::interrupt();

Expand Down
21 changes: 21 additions & 0 deletions mlir/test/Target/LLVMIR/openmp-target-nesting-in-host-ops.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,20 @@ module attributes {llvm.target_triple = "amdgcn-amd-amdhsa", omp.is_gpu = true,
llvm.return
}

llvm.func @test_target_and_atomic_update(%x: !llvm.ptr, %expr : i32) {
omp.target {
omp.terminator
}

omp.atomic.update %x : !llvm.ptr {
^bb0(%xval: i32):
%newval = llvm.add %xval, %expr : i32
omp.yield(%newval : i32)
}

llvm.return
}

// CHECK-LABEL: define void @test_nested_target_in_parallel_with_private({{.*}}) {
// CHECK: br label %omp.parallel.fake.region
// CHECK: omp.parallel.fake.region:
Expand Down Expand Up @@ -132,4 +146,11 @@ module attributes {llvm.target_triple = "amdgcn-amd-amdhsa", omp.is_gpu = true,
// CHECK: call void @__kmpc_target_deinit()
// CHECK: ret void
// CHECK: }

// CHECK-LABEL: define {{.*}} amdgpu_kernel void @__omp_offloading_{{.*}}_test_target_and_atomic_update_{{.*}} {
// CHECK: call i32 @__kmpc_target_init
// CHECK: user_code.entry:
// CHECK: call void @__kmpc_target_deinit()
// CHECK: ret void
// CHECK: }
}