[clang] [llvm] [clang][CodeGen] `used` globals && the payloads for global ctors & dtors are globals (PR #93601)
Alex Voicu via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 3 16:12:01 PDT 2024
https://github.com/AlexVlx updated https://github.com/llvm/llvm-project/pull/93601
>From 34b9646a38c6bdd0419dd9d2eb1bc847c4d16596 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Tue, 28 May 2024 20:09:15 +0100
Subject: [PATCH 1/7] Fix `emitUsed` to place `used` globals in the Global AS.
Update tests accordingly.
---
clang/lib/CodeGen/CodeGenModule.cpp | 11 ++++++-----
clang/test/CodeGen/2005-12-04-AttributeUsed.c | 2 ++
clang/test/CodeGen/attr-retain.c | 4 +++-
clang/test/CodeGenCUDA/llvm-used.cu | 7 +++++--
clang/test/CodeGenCXX/attr-retain.cpp | 2 ++
...static-member-variable-explicit-specialization.cpp | 6 +++++-
.../test/OpenMP/amdgcn_target_global_constructor.cpp | 4 ++--
7 files changed, 25 insertions(+), 11 deletions(-)
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]+]] {
>From 90cd705b63cbdf1939b61b07a11d94abbcdea3ec Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Tue, 28 May 2024 20:30:00 +0100
Subject: [PATCH 2/7] Fix formatting.
---
clang/lib/CodeGen/CodeGenModule.cpp | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 30a18b1c5e7a8..397c611b3ea33 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2048,8 +2048,8 @@ void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) {
TheModule.getDataLayout().getProgramAddressSpace());
// Get the type of a ctor entry, { i32, program void ()*, global i8* }.
- llvm::StructType *CtorStructTy = llvm::StructType::get(
- Int32Ty, CtorPFTy, GlobalsInt8PtrTy);
+ llvm::StructType *CtorStructTy =
+ llvm::StructType::get(Int32Ty, CtorPFTy, GlobalsInt8PtrTy);
// Construct the constructor and destructor arrays.
ConstantInitBuilder builder(*this);
@@ -2068,7 +2068,7 @@ void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) {
auto list =
ctors.finishAndCreateGlobal(GlobalName, getPointerAlign(),
/*constant*/ false,
- llvm::GlobalValue::AppendingLinkage);
+ llvm::GlobalValue::AppendingLinkage, );
// The LTO linker doesn't seem to like it when we set an alignment
// on appending variables. Take it off as a workaround.
@@ -2926,15 +2926,14 @@ static void emitUsed(CodeGenModule &CGM, StringRef Name,
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::getPointerBitCastOrAddrSpaceCast(
+ cast<llvm::Constant>(&*List[i]), CGM.GlobalsInt8PtrTy);
}
if (UsedArray.empty())
return;
- llvm::ArrayType *ATy = llvm::ArrayType::get(CGM.GlobalsInt8PtrTy,
- UsedArray.size());
+ llvm::ArrayType *ATy =
+ llvm::ArrayType::get(CGM.GlobalsInt8PtrTy, UsedArray.size());
auto *GV = new llvm::GlobalVariable(
CGM.getModule(), ATy, false, llvm::GlobalValue::AppendingLinkage,
>From 780f541ed427ad847ec80dd5dd6cc602ef9a01da Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Tue, 28 May 2024 20:44:53 +0100
Subject: [PATCH 3/7] Delete accidental noise.
---
clang/lib/CodeGen/CodeGenModule.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 397c611b3ea33..4346ea7b1b6ad 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2068,7 +2068,7 @@ void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) {
auto list =
ctors.finishAndCreateGlobal(GlobalName, getPointerAlign(),
/*constant*/ false,
- llvm::GlobalValue::AppendingLinkage, );
+ llvm::GlobalValue::AppendingLinkage);
// The LTO linker doesn't seem to like it when we set an alignment
// on appending variables. Take it off as a workaround.
>From ddc701a16dd42df6057d05cd5d94506c23e4057d Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Fri, 31 May 2024 03:21:07 +0100
Subject: [PATCH 4/7] Fork out global ctor/dtor changes.
---
clang/lib/CodeGen/CodeGenModule.cpp | 8 ++++----
clang/test/OpenMP/amdgcn_target_global_constructor.cpp | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 4346ea7b1b6ad..5657615f34c05 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, program void ()*, global i8* }.
- llvm::StructType *CtorStructTy =
- llvm::StructType::get(Int32Ty, CtorPFTy, GlobalsInt8PtrTy);
+ // Get the type of a ctor entry, { i32, void ()*, i8* }.
+ llvm::StructType *CtorStructTy = llvm::StructType::get(
+ Int32Ty, CtorPFTy, VoidPtrTy);
// 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(GlobalsInt8PtrTy);
+ ctor.addNullPointer(VoidPtrTy);
ctor.finishAndAddTo(ctors);
}
diff --git a/clang/test/OpenMP/amdgcn_target_global_constructor.cpp b/clang/test/OpenMP/amdgcn_target_global_constructor.cpp
index cc9dd56615dc6..80a5067b357a2 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 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: @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-LABEL: define {{[^@]+}}@__cxx_global_var_init
// CHECK-SAME: () #[[ATTR0:[0-9]+]] {
>From a13b3b03baccaa6a886f313869ecd8e142eeeac7 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Mon, 3 Jun 2024 21:50:08 +0100
Subject: [PATCH 5/7] Switch to using unqualified pointers.
---
clang/lib/CodeGen/CodeGenModule.cpp | 9 +++++----
clang/test/CodeGen/2005-12-04-AttributeUsed.c | 2 +-
clang/test/CodeGen/attr-retain.c | 4 ++--
clang/test/CodeGenCUDA/llvm-used.cu | 7 ++-----
clang/test/CodeGenCXX/attr-retain.cpp | 2 +-
.../static-member-variable-explicit-specialization.cpp | 4 ----
6 files changed, 11 insertions(+), 17 deletions(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 5657615f34c05..0e2bbd3127806 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2922,18 +2922,19 @@ static void emitUsed(CodeGenModule &CGM, StringRef Name,
if (List.empty())
return;
+ llvm::Type *UsedPtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
+
// 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(
+ cast<llvm::Constant>(&*List[i]), UsedPtrTy);
}
if (UsedArray.empty())
return;
- llvm::ArrayType *ATy =
- llvm::ArrayType::get(CGM.GlobalsInt8PtrTy, UsedArray.size());
+ llvm::ArrayType *ATy = llvm::ArrayType::get(UsedPtrTy, 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 c5089d9bda2c6..5a5ec3c6ec9d5 100644
--- a/clang/test/CodeGen/2005-12-04-AttributeUsed.c
+++ b/clang/test/CodeGen/2005-12-04-AttributeUsed.c
@@ -2,7 +2,7 @@
// 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"
+// GLOBALAS: @llvm.compiler.used = appending addrspace(1) global [2 x ptr] [ptr @foo, ptr addrspacecast (ptr addrspace(1) @X to ptr)], 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 e86f6ae8ed06c..bbeccad4411e9 100644
--- a/clang/test/CodeGen/attr-retain.c
+++ b/clang/test/CodeGen/attr-retain.c
@@ -12,8 +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"
+// GLOBALAS: @llvm.used = appending addrspace(1) global [8 x ptr] [ptr addrspacecast (ptr addrspace(4) @c0 to ptr), ptr addrspacecast (ptr addrspace(1) @foo.l0 to ptr), ptr @f0, ptr @f2, ptr addrspacecast (ptr addrspace(1) @g0 to ptr), ptr addrspacecast (ptr addrspace(1) @g1 to ptr), ptr addrspacecast (ptr addrspace(1) @g3 to ptr), ptr addrspacecast (ptr addrspace(1) @g4 to ptr)], section "llvm.metadata"
+// GLOBALAS: appending addrspace(1) global [3 x ptr] [ptr @f2, ptr addrspacecast (ptr addrspace(1) @g3 to ptr), ptr addrspacecast (ptr addrspace(1) @g4 to ptr)], 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 7782048b52836..c39111dd48036 100644
--- a/clang/test/CodeGenCUDA/llvm-used.cu
+++ b/clang/test/CodeGenCUDA/llvm-used.cu
@@ -1,11 +1,8 @@
// 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 iff necessary.
-// PR22383 exposed an issue where we were generating a bitcast instead of an
-// addrspacecast.
+// Make sure we emit the proper addrspacecast for llvm.used. 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 73c649ae972bf..d22713d9cf20f 100644
--- a/clang/test/CodeGenCXX/attr-retain.cpp
+++ b/clang/test/CodeGenCXX/attr-retain.cpp
@@ -2,7 +2,7 @@
// 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)]
+// GLOBALAS: @llvm.used = appending addrspace(1) global [7 x ptr]
// 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 04d29cf1cea51..e05221985fa7f 100644
--- a/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
+++ b/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
@@ -1,8 +1,6 @@
// 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 {
@@ -14,7 +12,6 @@ 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
@@ -82,7 +79,6 @@ template<> int A<bool>::a = 10;
/// 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();
>From 86dc6ba14f10dde87b9cf1d8f8a2230809a6e495 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Mon, 3 Jun 2024 23:28:57 +0100
Subject: [PATCH 6/7] Update LangRef.
---
llvm/docs/LangRef.rst | 43 ++++++++++++++++++++++---------------------
1 file changed, 22 insertions(+), 21 deletions(-)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 614dd98b013b3..06d014592b88b 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -354,7 +354,7 @@ added in the future:
not be used lightly but only for specific situations such as an
alternative to the *register pinning* performance technique often
used when implementing functional programming languages. At the
- moment only X86, AArch64, and RISCV support this convention. The
+ moment only X86, AArch64, and RISCV support this convention. The
following limitations exist:
- On *X86-32* only up to 4 bit type parameters are supported. No
@@ -685,10 +685,10 @@ implementation defined, the optimizer can't do the latter. The former is
challenging as many commonly expected properties, such as
``ptrtoint(v)-ptrtoint(v) == 0``, don't hold for non-integral types.
Similar restrictions apply to intrinsics that might examine the pointer bits,
-such as :ref:`llvm.ptrmask<int_ptrmask>`.
+such as :ref:`llvm.ptrmask<int_ptrmask>`.
The alignment information provided by the frontend for a non-integral pointer
-(typically using attributes or metadata) must be valid for every possible
+(typically using attributes or metadata) must be valid for every possible
representation of the pointer.
.. _globalvars:
@@ -1649,10 +1649,10 @@ Currently, only the following parameter attributes are defined:
- Both ``a`` and ``b`` are constants.
- The range is allowed to wrap.
- The range should not represent the full or empty set. That is, ``a!=b``.
-
- This attribute may only be applied to parameters or return values with integer
+
+ This attribute may only be applied to parameters or return values with integer
or vector of integer types.
-
+
For vector-typed parameters, the range is applied element-wise.
.. _gc:
@@ -8602,8 +8602,9 @@ The '``llvm.used``' Global Variable
The ``@llvm.used`` global is an array which has
:ref:`appending linkage <linkage_appending>`. This array contains a list of
pointers to named global variables, functions and aliases which may optionally
-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 pointers are
+intentionally left unqualified to underline their ephemeral nature. For example,
+a legal use of it is:
.. code-block:: llvm
@@ -14214,7 +14215,7 @@ Arguments:
""""""""""
The first 4 arguments are similar to ``llvm.instrprof.increment``. The indexing
is specific to callsites, meaning callsites are indexed from 0, independent from
-the indexes used by the other intrinsics (such as
+the indexes used by the other intrinsics (such as
``llvm.instrprof.increment[.step]``).
The last argument is the called value of the callsite this intrinsic precedes.
@@ -14228,7 +14229,7 @@ a buffer LLVM can use to perform counter increments (i.e. the lowering of
``llvm.instrprof.increment[.step]``. The address range following the counter
buffer, ``<num-counters>`` x ``sizeof(ptr)`` - sized, is expected to contain
pointers to contexts of functions called from this function ("subcontexts").
-LLVM does not dereference into that memory region, just calculates GEPs.
+LLVM does not dereference into that memory region, just calculates GEPs.
The lowering of ``llvm.instrprof.callsite`` consists of:
@@ -14848,8 +14849,8 @@ integer bit width or any vector of integer elements.
Overview:
"""""""""
-Return ``-1`` if ``%a`` is signed less than ``%b``, ``0`` if they are equal, and
-``1`` if ``%a`` is signed greater than ``%b``. Vector intrinsics operate on a per-element basis.
+Return ``-1`` if ``%a`` is signed less than ``%b``, ``0`` if they are equal, and
+``1`` if ``%a`` is signed greater than ``%b``. Vector intrinsics operate on a per-element basis.
Arguments:
""""""""""
@@ -14877,8 +14878,8 @@ integer bit width or any vector of integer elements.
Overview:
"""""""""
-Return ``-1`` if ``%a`` is unsigned less than ``%b``, ``0`` if they are equal, and
-``1`` if ``%a`` is unsigned greater than ``%b``. Vector intrinsics operate on a per-element basis.
+Return ``-1`` if ``%a`` is unsigned less than ``%b``, ``0`` if they are equal, and
+``1`` if ``%a`` is unsigned greater than ``%b``. Vector intrinsics operate on a per-element basis.
Arguments:
""""""""""
@@ -20940,9 +20941,9 @@ Semantics:
""""""""""
The '``llvm.vp.minimum``' intrinsic performs floating-point minimum (:ref:`minimum <i_minimum>`)
-of the first and second vector operand on each enabled lane, the result being
+of the first and second vector operand on each enabled lane, the result being
NaN if either operand is a NaN. -0.0 is considered to be less than +0.0 for this
-intrinsic. The result on disabled lanes is a :ref:`poison value <poisonvalues>`.
+intrinsic. The result on disabled lanes is a :ref:`poison value <poisonvalues>`.
The operation is performed in the default floating-point environment.
Examples:
@@ -20990,9 +20991,9 @@ Semantics:
""""""""""
The '``llvm.vp.maximum``' intrinsic performs floating-point maximum (:ref:`maximum <i_maximum>`)
-of the first and second vector operand on each enabled lane, the result being
+of the first and second vector operand on each enabled lane, the result being
NaN if either operand is a NaN. -0.0 is considered to be less than +0.0 for this
-intrinsic. The result on disabled lanes is a :ref:`poison value <poisonvalues>`.
+intrinsic. The result on disabled lanes is a :ref:`poison value <poisonvalues>`.
The operation is performed in the default floating-point environment.
Examples:
@@ -28269,7 +28270,7 @@ Semantics:
""""""""""
The intrinsic ``@llvm.allow.ubsan.check()`` returns either ``true`` or
-``false``, depending on compiler options.
+``false``, depending on compiler options.
For each evaluation of a call to this intrinsic, the program must be valid and
correct both if it returns ``true`` and if it returns ``false``.
@@ -28328,13 +28329,13 @@ Semantics:
""""""""""
The intrinsic ``@llvm.allow.runtime.check()`` returns either ``true`` or
-``false``, depending on compiler options.
+``false``, depending on compiler options.
For each evaluation of a call to this intrinsic, the program must be valid and
correct both if it returns ``true`` and if it returns ``false``.
When used in a branch condition, it allows us to choose between
-two alternative correct solutions for the same problem.
+two alternative correct solutions for the same problem.
If the intrinsic is evaluated as ``true``, program should execute a guarded
check. If the intrinsic is evaluated as ``false``, the program should avoid any
>From 3f93c20a27242ead194f941bfabefc4da85ddd60 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Tue, 4 Jun 2024 00:11:45 +0100
Subject: [PATCH 7/7] Add clarifying comment.
---
clang/lib/CodeGen/CodeGenModule.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 0918ddab584ac..0bdd555428828 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2922,6 +2922,8 @@ static void emitUsed(CodeGenModule &CGM, StringRef Name,
if (List.empty())
return;
+ // We unconditionally use unqualified pointers - this is intentional as these
+ // are fake / ephemeral globals, serving only as lifetime extension hooks
llvm::Type *UsedPtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
// Convert List to what ConstantArray needs.
More information about the llvm-commits
mailing list