Skip to content

[clang][CodeGen] used globals are fake #93601

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

AlexVlx
Copy link
Contributor

@AlexVlx AlexVlx commented May 28, 2024

Currently we:

  • emit the elements of the used and compiler.used arrays as default pointers
  • assume that the payloads for global ctors/dtors reside in the default AS, and thus use a default pointer to access them

Both of these assumptions appear overly conservative, as neither of the above can be anything but a global. This patch, changes emitUsed and CodeGenModule::EmitCtorListto correctly reflect this by using GlobalsInt8PtrTy as the pointer type for both cases. Existing tests are extended to include a target (AMDGCN) which has an explicit, non-zero, global AS.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. clang:openmp OpenMP related changes to Clang labels May 28, 2024
@llvmbot
Copy link
Member

llvmbot commented May 28, 2024

@llvm/pr-subscribers-llvm-ir
@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-clang

Author: Alex Voicu (AlexVlx)

Changes

Currently we:

  • emit the elements of the used and compiler.used arrays as default pointers
  • assume that the payloads for global ctors/dtors reside in the default AS, and thus use a default pointer to access them

Both of these assumptions appear overly conservative, as neither of the above can be anything but a global. This patch, changes emitUsed and CodeGenModule::EmitCtorListto correctly reflect this by using GlobalsInt8PtrTy as the pointer type for both cases. Existing tests are extended to include a target (AMDGCN) which has an explicit, non-zero, global AS.


Full diff: https://github.com/llvm/llvm-project/pull/93601.diff

7 Files Affected:

  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+6-5)
  • (modified) clang/test/CodeGen/2005-12-04-AttributeUsed.c (+2)
  • (modified) clang/test/CodeGen/attr-retain.c (+3-1)
  • (modified) clang/test/CodeGenCUDA/llvm-used.cu (+5-2)
  • (modified) clang/test/CodeGenCXX/attr-retain.cpp (+2)
  • (modified) clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp (+5-1)
  • (modified) clang/test/OpenMP/amdgcn_target_global_constructor.cpp (+2-2)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index e4774a587707a..30a18b1c5e7a8 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2047,9 +2047,9 @@ void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) {
   llvm::Type *CtorPFTy = llvm::PointerType::get(CtorFTy,
       TheModule.getDataLayout().getProgramAddressSpace());
 
-  // Get the type of a ctor entry, { i32, void ()*, i8* }.
+  // Get the type of a ctor entry, { i32, program void ()*, global i8* }.
   llvm::StructType *CtorStructTy = llvm::StructType::get(
-      Int32Ty, CtorPFTy, VoidPtrTy);
+      Int32Ty, CtorPFTy, GlobalsInt8PtrTy);
 
   // Construct the constructor and destructor arrays.
   ConstantInitBuilder builder(*this);
@@ -2061,7 +2061,7 @@ void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) {
     if (I.AssociatedData)
       ctor.add(I.AssociatedData);
     else
-      ctor.addNullPointer(VoidPtrTy);
+      ctor.addNullPointer(GlobalsInt8PtrTy);
     ctor.finishAndAddTo(ctors);
   }
 
@@ -2928,12 +2928,13 @@ static void emitUsed(CodeGenModule &CGM, StringRef Name,
   for (unsigned i = 0, e = List.size(); i != e; ++i) {
     UsedArray[i] =
         llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
-            cast<llvm::Constant>(&*List[i]), CGM.Int8PtrTy);
+            cast<llvm::Constant>(&*List[i]), CGM.GlobalsInt8PtrTy);
   }
 
   if (UsedArray.empty())
     return;
-  llvm::ArrayType *ATy = llvm::ArrayType::get(CGM.Int8PtrTy, UsedArray.size());
+  llvm::ArrayType *ATy = llvm::ArrayType::get(CGM.GlobalsInt8PtrTy,
+                                              UsedArray.size());
 
   auto *GV = new llvm::GlobalVariable(
       CGM.getModule(), ATy, false, llvm::GlobalValue::AppendingLinkage,
diff --git a/clang/test/CodeGen/2005-12-04-AttributeUsed.c b/clang/test/CodeGen/2005-12-04-AttributeUsed.c
index bd232831fe1a6..c5089d9bda2c6 100644
--- a/clang/test/CodeGen/2005-12-04-AttributeUsed.c
+++ b/clang/test/CodeGen/2005-12-04-AttributeUsed.c
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 %s -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck %s --check-prefix=GLOBALAS
 
 // CHECK: @llvm.used = appending global [2 x ptr] [ptr @foo, ptr @X], section "llvm.metadata"
+// GLOBALAS: @llvm.compiler.used = appending addrspace(1) global [2 x ptr addrspace(1)] [ptr addrspace(1) addrspacecast (ptr @foo to ptr addrspace(1)), ptr addrspace(1) @X], section "llvm.metadata"
 int X __attribute__((used));
 int Y;
 
diff --git a/clang/test/CodeGen/attr-retain.c b/clang/test/CodeGen/attr-retain.c
index fc41be76f9d0a..e86f6ae8ed06c 100644
--- a/clang/test/CodeGen/attr-retain.c
+++ b/clang/test/CodeGen/attr-retain.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -emit-llvm -triple x86_64 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple amdgcn-amd-amdhsa %s -o - | FileCheck %s --check-prefix=GLOBALAS
 
 /// Set !retain regardless of the target. The backend will lower !retain to
 /// SHF_GNU_RETAIN on ELF and ignore the metadata for other binary formats.
@@ -11,7 +12,8 @@
 
 // CHECK:      @llvm.used = appending global [8 x ptr] [ptr @c0, ptr @foo.l0, ptr @f0, ptr @f2, ptr @g0, ptr @g1, ptr @g3, ptr @g4], section "llvm.metadata"
 // CHECK:      @llvm.compiler.used = appending global [3 x ptr] [ptr @f2, ptr @g3, ptr @g4], section "llvm.metadata"
-
+// GLOBALAS:   @llvm.used = appending addrspace(1) global [8 x ptr addrspace(1)] [ptr addrspace(1) addrspacecast (ptr addrspace(4) @c0 to ptr addrspace(1)), ptr addrspace(1) @foo.l0, ptr addrspace(1) addrspacecast (ptr @f0 to ptr addrspace(1)), ptr addrspace(1) addrspacecast (ptr @f2 to ptr addrspace(1)), ptr addrspace(1) @g0, ptr addrspace(1) @g1, ptr addrspace(1) @g3, ptr addrspace(1) @g4], section "llvm.metadata"
+// GLOBALAS:   @llvm.compiler.used = appending addrspace(1) global [3 x ptr addrspace(1)] [ptr addrspace(1) addrspacecast (ptr @f2 to ptr addrspace(1)), ptr addrspace(1) @g3, ptr addrspace(1) @g4], section "llvm.metadata"
 const int c0 __attribute__((retain)) = 42;
 
 void foo(void) {
diff --git a/clang/test/CodeGenCUDA/llvm-used.cu b/clang/test/CodeGenCUDA/llvm-used.cu
index c39111dd48036..7782048b52836 100644
--- a/clang/test/CodeGenCUDA/llvm-used.cu
+++ b/clang/test/CodeGenCUDA/llvm-used.cu
@@ -1,8 +1,11 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - -fcuda-is-device -triple nvptx64-unknown-unknown | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -fcuda-is-device -triple amdgcn-amd-amdhsa | FileCheck %s --check-prefix=NOASCAST
 
 
-// Make sure we emit the proper addrspacecast for llvm.used.  PR22383 exposed an
-// issue where we were generating a bitcast instead of an addrspacecast.
+// Make sure we emit the proper addrspacecast for llvm.used iff necessary.
+// PR22383 exposed an issue where we were generating a bitcast instead of an
+// addrspacecast.
 
 // CHECK: @llvm.compiler.used = appending global [1 x ptr] [ptr addrspacecast (ptr addrspace(1) @a to ptr)], section "llvm.metadata"
+// NOASCAST: @llvm.compiler.used = appending addrspace(1) global [1 x ptr addrspace(1)] [ptr addrspace(1) @a], section "llvm.metadata"
 __attribute__((device)) __attribute__((__used__)) int a[] = {};
diff --git a/clang/test/CodeGenCXX/attr-retain.cpp b/clang/test/CodeGenCXX/attr-retain.cpp
index 3a56576d81632..73c649ae972bf 100644
--- a/clang/test/CodeGenCXX/attr-retain.cpp
+++ b/clang/test/CodeGenCXX/attr-retain.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -Werror %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple amdgcn-amd-amdhsa -Werror %s -o - | FileCheck %s --check-prefix=GLOBALAS
 
 // CHECK:      @llvm.used = appending global [7 x ptr]
+// GLOBALAS:   @llvm.used = appending addrspace(1) global [7 x ptr addrspace(1)]
 // CHECK-SAME:   @_ZN2X0C2Ev
 // CHECK-SAME:   @_ZN2X0C1Ev
 // CHECK-SAME:   @_ZN2X0D2Ev
diff --git a/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp b/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
index 46c4c4d391769..04d29cf1cea51 100644
--- a/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
+++ b/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 %s -std=c++1y -triple=x86_64-pc-linux -emit-llvm -o - | FileCheck --check-prefix=ELF --check-prefix=ALL %s
 // RUN: %clang_cc1 %s -std=c++1y -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck --check-prefix=MACHO --check-prefix=ALL %s
 // RUN: %clang_cc1 %s -std=c++1y -triple=x86_64-pc-linux -emit-llvm -fdeclspec -DSELECTANY -o - | FileCheck --check-prefix=ELF-SELECTANY %s
+// RUN: %clang_cc1 %s -std=c++1y -triple=amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck --check-prefix=GLOBALAS-ELF %s
+// RUN: %clang_cc1 %s -std=c++1y -triple=amdgcn-amd-amdhsa -emit-llvm -fdeclspec -DSELECTANY -o - | FileCheck --check-prefix=GLOBALAS-ELF-SELECTANY %s
 
 #ifdef SELECTANY
 struct S {
@@ -12,6 +14,7 @@ int f();
 
 // ELF-SELECTANY: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init, ptr @selectany }]
 // ELF-SELECTANY: @llvm.used = appending global [1 x ptr] [ptr @selectany]
+// GLOBALAS-ELF-SELECTANY: @llvm.used = appending addrspace(1) global [1 x ptr addrspace(1)] [ptr addrspace(1) @selectany]
 int __declspec(selectany) selectany = f();
 
 #else
@@ -73,12 +76,13 @@ template<> int A<bool>::a = 10;
 // MACHO: { i32, ptr, ptr } { i32 65535, ptr @[[unordered22:[^,]*]], ptr null },
 
 // ELF:  { i32, ptr, ptr } { i32 65535, ptr @[[unordered21:[^,]*]], ptr @_ZN4Fib2ILi5EE1aE },
-// MACHO: { i32, ptr, ptr } { i32 65535, ptr @[[unordered21:[^,]*]], ptr null }, 
+// MACHO: { i32, ptr, ptr } { i32 65535, ptr @[[unordered21:[^,]*]], ptr null },
 
 // ALL:  { i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp, ptr null }]
 
 /// llvm.used ensures SHT_INIT_ARRAY in a section group cannot be GCed.
 // ELF: @llvm.used = appending global [14 x ptr] [ptr @_ZN1AIsE1aE, ptr @_Z1xIsE, ptr @_ZN2ns1aIiE1iE, ptr @_ZN2ns1b1iIiEE, ptr @_ZN1AIvE1aE, ptr @_Z1xIcE, ptr @_ZN3FibILi5EE1aE, ptr @_ZN3FibILi3EE1aE, ptr @_ZN3FibILi2EE1aE, ptr @_ZN3FibILi4EE1aE, ptr @_ZN4Fib2ILi5EE1aE, ptr @_ZN4Fib2ILi4EE1aE, ptr @_ZN4Fib2ILi2EE1aE, ptr @_ZN4Fib2ILi3EE1aE]
+// GLOBALAS-ELF: @llvm.used = appending addrspace(1) global [14 x ptr addrspace(1)] [ptr addrspace(1) @_ZN1AIsE1aE, ptr addrspace(1) @_Z1xIsE, ptr addrspace(1) @_ZN2ns1aIiE1iE, ptr addrspace(1) @_ZN2ns1b1iIiEE, ptr addrspace(1) @_ZN1AIvE1aE, ptr addrspace(1) @_Z1xIcE, ptr addrspace(1) @_ZN3FibILi5EE1aE, ptr addrspace(1) @_ZN3FibILi3EE1aE, ptr addrspace(1) @_ZN3FibILi2EE1aE, ptr addrspace(1) @_ZN3FibILi4EE1aE, ptr addrspace(1) @_ZN4Fib2ILi5EE1aE, ptr addrspace(1) @_ZN4Fib2ILi4EE1aE, ptr addrspace(1) @_ZN4Fib2ILi2EE1aE, ptr addrspace(1) @_ZN4Fib2ILi3EE1aE], section "llvm.metadata"
 
 template int A<short>::a;  // Unordered
 int b = foo();
diff --git a/clang/test/OpenMP/amdgcn_target_global_constructor.cpp b/clang/test/OpenMP/amdgcn_target_global_constructor.cpp
index 80a5067b357a2..cc9dd56615dc6 100644
--- a/clang/test/OpenMP/amdgcn_target_global_constructor.cpp
+++ b/clang/test/OpenMP/amdgcn_target_global_constructor.cpp
@@ -21,8 +21,8 @@ S A;
 
 #endif
 //.
-// CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__sub_I_amdgcn_target_global_constructor.cpp, ptr null }]
-// CHECK: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @__dtor_A, ptr null }]
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr addrspace(1) }] [{ i32, ptr, ptr addrspace(1) } { i32 65535, ptr @_GLOBAL__sub_I_amdgcn_target_global_constructor.cpp, ptr addrspace(1) null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr addrspace(1) }] [{ i32, ptr, ptr addrspace(1) } { i32 65535, ptr @__dtor_A, ptr addrspace(1) null }]
 //.
 // CHECK-LABEL: define {{[^@]+}}@__cxx_global_var_init
 // CHECK-SAME: () #[[ATTR0:[0-9]+]] {

@AlexVlx AlexVlx removed clang Clang issues not falling into any other category clang:openmp OpenMP related changes to Clang labels May 28, 2024
@AlexVlx AlexVlx changed the title used globals && the payloads for global ctors & dtors are globals [clang][CodeGen] used globals && the payloads for global ctors & dtors are globals May 28, 2024
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:openmp OpenMP related changes to Clang labels May 28, 2024
Copy link

github-actions bot commented May 28, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@@ -2928,12 +2928,13 @@ static void emitUsed(CodeGenModule &CGM, StringRef Name,
for (unsigned i = 0, e = List.size(); i != e; ++i) {
UsedArray[i] =
llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
cast<llvm::Constant>(&*List[i]), CGM.Int8PtrTy);
Copy link
Contributor

Choose a reason for hiding this comment

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

I got confused on the other thread. Is Int8PtrTy not always AS 0 in this case? I think always emitting used/compiler.used as a hardcoded addrspace 0 (IR 0, having nothing to do with the language or LangAS mapping) would be fine

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, Int8PtrTy is (now, after the change in the other thread) whatever LangAS::Default ends up mapping to. The idea being that the target would pick / reflect a contextually sane mapping. The one worry I have re: doing Unqual (just 0) here is that I suspect (but would have to check) that we'll then have to deal with invalid casts, where you have the target's 0 being e.g. private, and this line would try to ASCast from a Constant that'd be in global (for e.g. the SPIRV target this'd actually happen, global is 1 and private is 0). Or are you thinking we'd populate these differently, somehow?

Copy link
Contributor

Choose a reason for hiding this comment

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

For the purpose of used/compiler_used, I think it's best to ignore the language address space map (reiterating that the IR address space has little to do with the language). Just treat it as a special global that always uses addrspace(0). The required addrspacecasts will be inserted to 0, so it just leaves this as the status quo. It doesn't really matter if the target considers the casts valid or not, the used variables never codegened.

If we really had to go out of our way to avoid illegal constant expression casts, we'd probably have to have multiple used intrinsic variables per address space. In a better future we wouldn't allow constantexpr addrspacecasts, and then we'd also need to come up with another solution

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I'm still struggling to see why it is best create (possibly) broken IR, super heroic "but let us build an even more complicated devices like multiple intrinsics per AS, and also redo how ASCasts work etc." and rely on implicit knowledge about what happens with used and compiler.used (ah, because these are never CodeGen-ed, it's fine to do whatever). What's the actual benefit here? Why not make it a special global that uses AS 42, since that'd actually signal it's special, as opposed to Unqual/0, which do the exact contrary. I'm also struggling to see the backwards compat angle since we do not guarantee IR-level compat between LLVM versions (yes it frequently works but it's not guaranteed to).

Copy link
Contributor

@arsenm arsenm May 30, 2024

Choose a reason for hiding this comment

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

Ok, I'm still struggling to see why it is best create (possibly) broken IR

It's not broken. It just needs to provide a use, and whatever casts are there do not matter. We can write whatever rules we want and have the verifier enforce it. Currently we don't have any generic concept of "illegal addrspacecasts" (relatedly we should probably stop throwing codegen errors on the cases we don't handle, and just lower them to poison)

Why not make it a special global that uses AS 42

Behavior of address spaces are target defined. We don't want to just grab random numbers for generic purposes. We've gradually been migrating away from 0 being special in more contexts, but nothing has been done for used (and I don't see a particularly compelling reason to do, used just needs to be a box that is a use)

IR-level compat between LLVM versions (yes it frequently works but it's not guaranteed to).

We do guarantee forward compatible bitcode. We've just done a bad job at it for some target stuff, particularly in cases where subtarget feature names have leaked into the IR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Apologies, I still don't see the actual benefit being spelled out, I might be missing the obvious. I'll try again: I'm the FE (this is in Clang). I am emitting a global. Why would I do anything special here, versus emitting any other global, what am I gaining by not doing just that/losing by actually doing that. Surely it's straightforward to explain?

Copy link
Collaborator

Choose a reason for hiding this comment

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

We have HIP apps which ship bitcode library which may contain llvm.compiler.used or llvm.global_ctors which use addr space 0. If we switch to use addr space 1, the new HIP app may not be able to link with the existing bitcode libraries.

My understanding is that the addr space used in llvm.compiler.used or llvm.global_ctors do not really have meanings since no one loads or stores to them. As long as they are the same for different TU's it is fine. It should be OK to use addr space 0.

Copy link
Contributor

Choose a reason for hiding this comment

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

You aren't emitting a real global, it's this fake special case IR construct. It doesn't fit into the boxes provided by the target global/program/alloca address spaces

llvm::StructType *CtorStructTy = llvm::StructType::get(
Int32Ty, CtorPFTy, VoidPtrTy);
Int32Ty, CtorPFTy, GlobalsInt8PtrTy);
Copy link
Collaborator

Choose a reason for hiding this comment

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

better to emit pointer to addr space 0 instead of 1 to keep backward compatibility

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We cannot do this, for some targets 0 can point to something that does not work as a global at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

More specifically, we should not be emitting / relying on some numerical value, but rather assume that what the DataLayout encodes is sound.

Copy link
Contributor

Choose a reason for hiding this comment

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

What compatibility is broken here? Just bitcode loading? Do we just need to implement an autoupgrade for this?

Copy link
Member

Choose a reason for hiding this comment

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

The autoupgrade solution might be a bit cleaner since it would remove these address space casts for at least the globals. Function arguments could still require an AS cast, although in the CHERI backend case those are the same and we would be able to avoid all casts. As noted elsewhere the address space is somewhat irrelevant so also fine with keeping it as AS0.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The ctor/dtor stuff got forked into #93914, as @arsenm suggested.


// CHECK: @llvm.used = appending global [2 x ptr] [ptr @foo, ptr @X], section "llvm.metadata"
// GLOBALAS: @llvm.compiler.used = appending addrspace(1) global [2 x ptr addrspace(1)] [ptr addrspace(1) addrspacecast (ptr @foo to ptr addrspace(1)), ptr addrspace(1) @X], section "llvm.metadata"
Copy link
Contributor

Choose a reason for hiding this comment

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

Used really should use flat. It happens to be better for us that we can legally cast more things to addrspace(0) than to 1, but given how the IR currently works we should just assume used is as 0

@llvmbot llvmbot added the llvm:ir label Jun 3, 2024
Copy link
Member

@arichardson arichardson left a comment

Choose a reason for hiding this comment

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

Commit title needs updating to only refer to used metadata. A few wording suggestions inline.

@@ -2922,18 +2922,21 @@ static void emitUsed(CodeGenModule &CGM, StringRef Name,
if (List.empty())
return;

// We unconditionally use unqualified pointers - this is intentional as these
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// We unconditionally use unqualified pointers - this is intentional as these
// We unconditionally use AS0 pointers - this is intentional as these

Since this refers to LLVM and not Clang pointer types I'd use the address space terminology.

Comment on lines 8645 to 8647
have a pointer cast formed of bitcast or getelementptr. The pointers are
intentionally left unqualified to underline their ephemeral nature. For example,
a legal use of it is:
Copy link
Member

@arichardson arichardson Jun 5, 2024

Choose a reason for hiding this comment

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

Suggested change
have a pointer cast formed of bitcast or getelementptr. The pointers are
intentionally left unqualified to underline their ephemeral nature. For example,
a legal use of it is:
have a pointer cast formed of bitcast or getelementptr. The address space of the
pointers is always zero rather than the globals address space since these are not
real global references but rather a special marker for the code emission logic.
For example, a legal use of it is:

Maybe something like this would be clearer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, this does sound much better so I've incorporated it, with the exception of explicitly calling out zero as the AS, because I still think it's not good to make it more magical than it already is. Please let me know if that works.

Copy link
Contributor

@arsenm arsenm left a comment

Choose a reason for hiding this comment

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

lgtm with nit

// Convert List to what ConstantArray needs.
SmallVector<llvm::Constant*, 8> UsedArray;
UsedArray.resize(List.size());
for (unsigned i = 0, e = List.size(); i != e; ++i) {
UsedArray[i] = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
cast<llvm::Constant>(&*List[i]), CGM.GlobalsInt8PtrTy);
UsedArray[i] = llvm::ConstantExpr::getPointerCast(
Copy link
Contributor

Choose a reason for hiding this comment

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

Although we should get rid of it, getPointerBitCastOrAddrSpaceCast is the correct helper for now. We should have a getAddrSpaceCast that doesn't throw a fit on same typed pointers but getPointerCast will try to insert ptrtoint etc.

@@ -2922,18 +2922,19 @@ static void emitUsed(CodeGenModule &CGM, StringRef Name,
if (List.empty())
return;

llvm::Type *UsedPtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
Copy link
Contributor

Choose a reason for hiding this comment

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

Best to just use get(Ctx, 0)

@arsenm
Copy link
Contributor

arsenm commented Jun 6, 2024

Commit message also needs to be updated

@AlexVlx AlexVlx changed the title [clang][CodeGen] used globals && the payloads for global ctors & dtors are globals [clang][CodeGen] used globals are fake Jun 6, 2024
have a pointer cast formed of bitcast or getelementptr. For example, a legal
use of it is:
have a pointer cast formed of bitcast or getelementptr. The address space of the
pointers is always unspecified, rather than the globals address space, since
Copy link
Contributor

Choose a reason for hiding this comment

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

Do not say unspecified. Say it is the default address space. 0 is not an unspecified address space

Copy link
Member

@arichardson arichardson left a comment

Choose a reason for hiding this comment

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

LGTM with the outstanding comments addressed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang:openmp OpenMP related changes to Clang clang Clang issues not falling into any other category llvm:ir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants