[clang] 1d699bf - [OpenMP] Always apply target declarations to canonical definitions

Joseph Huber via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 27 07:15:16 PDT 2023


Author: Joseph Huber
Date: 2023-06-27T09:15:03-05:00
New Revision: 1d699bf2664d2a9e64024fd9eb87451d6360ea8c

URL: https://github.com/llvm/llvm-project/commit/1d699bf2664d2a9e64024fd9eb87451d6360ea8c
DIFF: https://github.com/llvm/llvm-project/commit/1d699bf2664d2a9e64024fd9eb87451d6360ea8c.diff

LOG: [OpenMP] Always apply target declarations to canonical definitions

This patch changes the handling of OpenMP to add the device attributes
to the canonical definitions when we encounter a non-canonical
definition. Previously, the following code would not work because it
would find the non-canonical definition first which would then not be
used anywhere else.

```
int x;
extern int x;
```

This patch now adds the attribute to both of them. This allows us to
perform the following operation if, for example, there were an
implementation of `stderr` on the device.

```
#include <stdio.h>

// List of libc symbols supported on the device.
extern FILE *stderr;
```

Unfortunately I cannot think of an equivalent solution to HIP / CUDA
device declarations as those are done with simple attributes. Attributes
themselves cannot be used to affect a definition once its canonical
definition has already been seen. Some help on that front would be
appreciated.

Fixes https://github.com/llvm/llvm-project/issues/63355

Reviewed By: ABataev

Differential Revision: https://reviews.llvm.org/D153369

Added: 
    

Modified: 
    clang/lib/AST/AttrImpl.cpp
    clang/test/OpenMP/declare_target_codegen.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp
index f41ab77ef164c9..f198a9acf8481f 100644
--- a/clang/lib/AST/AttrImpl.cpp
+++ b/clang/lib/AST/AttrImpl.cpp
@@ -151,14 +151,16 @@ void OMPDeclareTargetDeclAttr::printPrettyPragma(
 
 std::optional<OMPDeclareTargetDeclAttr *>
 OMPDeclareTargetDeclAttr::getActiveAttr(const ValueDecl *VD) {
-  if (!VD->hasAttrs())
+  if (llvm::all_of(VD->redecls(), [](const Decl *D) { return !D->hasAttrs(); }))
     return std::nullopt;
   unsigned Level = 0;
   OMPDeclareTargetDeclAttr *FoundAttr = nullptr;
-  for (auto *Attr : VD->specific_attrs<OMPDeclareTargetDeclAttr>()) {
-    if (Level <= Attr->getLevel()) {
-      Level = Attr->getLevel();
-      FoundAttr = Attr;
+  for (const Decl *D : VD->redecls()) {
+    for (auto *Attr : D->specific_attrs<OMPDeclareTargetDeclAttr>()) {
+      if (Level <= Attr->getLevel()) {
+        Level = Attr->getLevel();
+        FoundAttr = Attr;
+      }
     }
   }
   if (FoundAttr)

diff  --git a/clang/test/OpenMP/declare_target_codegen.cpp b/clang/test/OpenMP/declare_target_codegen.cpp
index aa7cf7bd038d42..f47335e2eea096 100644
--- a/clang/test/OpenMP/declare_target_codegen.cpp
+++ b/clang/test/OpenMP/declare_target_codegen.cpp
@@ -27,11 +27,13 @@
 // CHECK-DAG: Bake
 // CHECK-NOT: @{{hhh|ggg|fff|eee}} =
 // CHECK-DAG: @flag = protected global i8 undef,
+// CHECK-DAG: @dx = {{protected | }}global i32 0,
+// CHECK-DAG: @dy = {{protected | }}global i32 0,
 // CHECK-DAG: @aaa = external global i32,
-// CHECK-DAG: @bbb ={{ protected | }}global i32 0,
+// CHECK-DAG: @bbb = {{protected | }}global i32 0,
 // CHECK-DAG: weak constant %struct.__tgt_offload_entry { ptr @bbb,
 // CHECK-DAG: @ccc = external global i32,
-// CHECK-DAG: @ddd ={{ protected | }}global i32 0,
+// CHECK-DAG: @ddd = {{protected | }}global i32 0,
 // CHECK-DAG: @hhh_decl_tgt_ref_ptr = weak global ptr null
 // CHECK-DAG: @ggg_decl_tgt_ref_ptr = weak global ptr null
 // CHECK-DAG: @fff_decl_tgt_ref_ptr = weak global ptr null
@@ -51,10 +53,21 @@
 // CHECK-DAG: define {{.*}}i32 @{{.*}}{{foo|bar|baz2|baz3|FA|f_method}}{{.*}}()
 // CHECK-DAG: define {{.*}}void @{{.*}}TemplateClass{{.*}}(ptr {{[^,]*}} %{{.*}})
 // CHECK-DAG: define {{.*}}i32 @{{.*}}TemplateClass{{.*}}f_method{{.*}}(ptr {{[^,]*}} %{{.*}})
-// CHECK-DAG: define {{.*}}void @__omp_offloading_{{.*}}_globals_l[[@LINE+78]]_ctor()
+// CHECK-DAG: define {{.*}}void @__omp_offloading_{{.*}}_globals_l[[@LINE+89]]_ctor()
 
 #ifndef HEADER
 #define HEADER
+
+int dx = 0;
+extern int dx;
+#pragma omp declare target to(dx)
+
+int dy = 0;
+#pragma omp begin declare target
+
+extern int dy;
+#pragma omp end declare target
+
 #pragma omp declare target
 bool flag [[clang::loader_uninitialized]];
 extern int bbb;


        


More information about the cfe-commits mailing list