[PATCH] D133694: [Clang][OpenMP] Fix use_device_addr
Gheorghe-Teodor Bercea via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 12 06:44:48 PDT 2022
doru1004 created this revision.
Herald added subscribers: guansong, yaxunl.
Herald added a project: All.
doru1004 requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added subscribers: cfe-commits, sstefan1.
Herald added a project: clang.
With the current implementation, the use_device_addr does not correctly use a pointer that was already mapped to the device and ends up in segmentation fault. The test showcases the situation.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D133694
Files:
clang/lib/CodeGen/CGOpenMPRuntime.cpp
clang/lib/CodeGen/CGStmtOpenMP.cpp
clang/test/OpenMP/target_data_use_device_addr_codegen_ptr.cpp
Index: clang/test/OpenMP/target_data_use_device_addr_codegen_ptr.cpp
===================================================================
--- /dev/null
+++ clang/test/OpenMP/target_data_use_device_addr_codegen_ptr.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+int main() {
+ float x_array[256];
+ float *x = &x_array[0];
+
+ // make x available on the GPU
+ #pragma omp target data map(tofrom:x[0:256])
+ {
+ #pragma omp target data use_device_addr(x)
+ {
+ x[0] = 2;
+ }
+ }
+ return x[0] == 2;
+}
+
+// CHECK-LABEL: @main()
+// CHECK: [[X:%.+]] = alloca ptr, align 8
+// CHECK: call void @__tgt_target_data_begin_mapper(
+// CHECK: [[LOADED_X:%.+]] = load ptr, ptr [[X]], align 8
+// CHECK: [[BASE_PTR_GEP:%.+]] = getelementptr inbounds [1 x ptr], ptr [[OFFLOAD_BASE_PTR:%.+]], i32 0, i32 0
+// CHECK: store ptr [[LOADED_X]], ptr [[BASE_PTR_GEP]], align 8
+// CHECK: [[OFFLOAD_PTR_GEP:%.+]] = getelementptr inbounds [1 x ptr], ptr [[OFFLOAD_PTR:%.+]], i32 0, i32 0
+// CHECK: store ptr [[LOADED_X]], ptr [[OFFLOAD_PTR_GEP]], align 8
+// CHECK: getelementptr inbounds [1 x ptr], ptr [[OFFLOAD_BASE_PTR]], i32 0, i32 0
+// CHECK: getelementptr inbounds [1 x ptr], ptr [[OFFLOAD_PTR]], i32 0, i32 0
+// CHECK: call void @__tgt_target_data_begin_mapper(
+// CHECK: [[LOADED_DEVICE_X:%.+]] = load ptr, ptr [[BASE_PTR_GEP]], align 8
+// CHECK: %arrayidx5 = getelementptr inbounds float, ptr %13, i64 0
+// CHECK: store float 2.000000e+00, ptr %arrayidx5, align 4
+// CHECK: getelementptr inbounds [1 x ptr], ptr [[OFFLOAD_BASE_PTR]], i32 0, i32 0
+// CHECK: getelementptr inbounds [1 x ptr], ptr [[OFFLOAD_PTR]], i32 0, i32 0
+// CHECK: call void @__tgt_target_data_end_mapper(
+// CHECK: call void @__tgt_target_data_end_mapper(
+
+#endif
Index: clang/lib/CodeGen/CGStmtOpenMP.cpp
===================================================================
--- clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -7241,6 +7241,7 @@
// declaration used by the mapping logic. In some cases we may get
// OMPCapturedExprDecl that refers to the original declaration.
const ValueDecl *MatchingVD = OrigVD;
+ bool isPartOfAStruct = false;
if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {
// OMPCapturedExprDecl are used to privative fields of the current
// structure.
@@ -7248,6 +7249,7 @@
assert(isa<CXXThisExpr>(ME->getBase()) &&
"Base should be the current struct!");
MatchingVD = ME->getMemberDecl();
+ isPartOfAStruct = true;
}
// If we don't have information about the current list item, move on to
@@ -7259,8 +7261,11 @@
Address PrivAddr = InitAddrIt->getSecond();
// For declrefs and variable length array need to load the pointer for
// correct mapping, since the pointer to the data was passed to the runtime.
- if (isa<DeclRefExpr>(Ref->IgnoreParenImpCasts()) ||
- MatchingVD->getType()->isArrayType()) {
+ // Pointer types are already mapped correctly so no need to do a load unless
+ // the pointer type is part of a struct.
+ if ((isa<DeclRefExpr>(Ref->IgnoreParenImpCasts()) ||
+ MatchingVD->getType()->isArrayType()) &&
+ (isPartOfAStruct || !MatchingVD->getType()->isPointerType())) {
QualType PtrTy = getContext().getPointerType(
OrigVD->getType().getNonReferenceType());
PrivAddr = EmitLoadOfPointer(
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===================================================================
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -8691,7 +8691,7 @@
DeferredInfo[nullptr].emplace_back(IE, VD, /*ForDeviceAddr=*/true);
} else {
llvm::Value *Ptr;
- if (IE->isGLValue())
+ if (IE->isGLValue() && !IE->getType()->isPointerType())
Ptr = CGF.EmitLValue(IE).getPointer(CGF);
else
Ptr = CGF.EmitScalarExpr(IE);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D133694.459439.patch
Type: text/x-patch
Size: 4235 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220912/9ad871ef/attachment.bin>
More information about the cfe-commits
mailing list