diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 0abd5f76d449c..ee17d266e5057 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -850,8 +850,6 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { GV.getName() == "llvm.global_dtors")) { Check(!GV.hasInitializer() || GV.hasAppendingLinkage(), "invalid linkage for intrinsic global variable", &GV); - Check(GV.materialized_use_empty(), - "invalid uses of intrinsic global variable", &GV); // Don't worry about emitting an error for it not being an array, // visitGlobalValue will complain on appending non-array. diff --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp index 122279160cc7e..47c5aa0cb2541 100644 --- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp +++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp @@ -35,7 +35,8 @@ static void appendToGlobalArray(StringRef ArrayName, Module &M, Function *F, // to the list. SmallVector CurrentCtors; StructType *EltTy; - if (GlobalVariable *GVCtor = M.getNamedGlobal(ArrayName)) { + GlobalVariable *GVCtor = M.getNamedGlobal(ArrayName); + if (GVCtor) { EltTy = cast(GVCtor->getValueType()->getArrayElementType()); if (Constant *Init = GVCtor->getInitializer()) { unsigned n = Init->getNumOperands(); @@ -43,7 +44,6 @@ static void appendToGlobalArray(StringRef ArrayName, Module &M, Function *F, for (unsigned i = 0; i != n; ++i) CurrentCtors.push_back(cast(Init->getOperand(i))); } - GVCtor->eraseFromParent(); } else { EltTy = StructType::get(IRB.getInt32Ty(), PointerType::get(FnTy, F->getAddressSpace()), @@ -67,8 +67,14 @@ static void appendToGlobalArray(StringRef ArrayName, Module &M, Function *F, // Create the new global variable and replace all uses of // the old global variable with the new one. - (void)new GlobalVariable(M, NewInit->getType(), false, - GlobalValue::AppendingLinkage, NewInit, ArrayName); + auto *NewGVCtor = + new GlobalVariable(M, NewInit->getType(), false, + GlobalValue::AppendingLinkage, NewInit, ArrayName); + if (GVCtor) { + NewGVCtor->takeName(GVCtor); + GVCtor->replaceAllUsesWith(NewGVCtor); + GVCtor->eraseFromParent(); + } } void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data) { diff --git a/llvm/test/CodeGen/Generic/global-ctors-dtors-uses.ll b/llvm/test/CodeGen/Generic/global-ctors-dtors-uses.ll new file mode 100644 index 0000000000000..7b335ce7f692e --- /dev/null +++ b/llvm/test/CodeGen/Generic/global-ctors-dtors-uses.ll @@ -0,0 +1,9 @@ +;; Run opt with asan to trigger `appendToGlobalArray` call which should update uses of `llvm.global_ctors` +; RUN: opt -passes=asan -S %s -o - | FileCheck %s +; CHECK: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @foo, i32 0, i64 55764, ptr getelementptr inbounds ([1 x { i32, ptr, ptr }], ptr @llvm.global_ctors, i32 0, i32 0, i32 1)), ptr null }, { i32, ptr, ptr } { i32 1, ptr @asan.module_ctor, ptr @asan.module_ctor }] + +@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @foo, i32 0, i64 55764, ptr getelementptr inbounds ([1 x { i32, ptr, ptr }], ptr @llvm.global_ctors, i32 0, i32 0, i32 1)), ptr null }] + +define void @foo() { + ret void +} diff --git a/llvm/test/Verifier/global-ctors-dtors-uses.ll b/llvm/test/Verifier/global-ctors-dtors-uses.ll deleted file mode 100644 index 1af4fb7ca9c0e..0000000000000 --- a/llvm/test/Verifier/global-ctors-dtors-uses.ll +++ /dev/null @@ -1,16 +0,0 @@ -; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s - -; CHECK: invalid uses of intrinsic global variable -; CHECK-NEXT: ptr @llvm.global_ctors -@llvm.global_ctors = appending global [1 x { i32, ptr, ptr } ] [ - { i32, ptr, ptr } { i32 65535, ptr null, ptr null } -] - -; CHECK: invalid uses of intrinsic global variable -; CHECK-NEXT: ptr @llvm.global_dtors -@llvm.global_dtors = appending global [1 x { i32, ptr, ptr } ] [ - { i32, ptr, ptr } { i32 65535, ptr null, ptr null } -] - -@ctor_user = global ptr @llvm.global_ctors -@dtor_user = global ptr @llvm.global_dtors diff --git a/llvm/test/tools/llvm-reduce/remove-ifunc-program-addrspace.ll b/llvm/test/tools/llvm-reduce/remove-ifunc-program-addrspace.ll index e275d61764b21..9573c55030242 100644 --- a/llvm/test/tools/llvm-reduce/remove-ifunc-program-addrspace.ll +++ b/llvm/test/tools/llvm-reduce/remove-ifunc-program-addrspace.ll @@ -16,7 +16,7 @@ define void @existing_ctor() addrspace(1) { ; CHECK-FINAL: [[TABLE:@[0-9]+]] = internal addrspace(2) global [6 x ptr addrspace(1)] poison, align 8 ; CHECK-FINAL: @llvm.global_ctors = appending addrspace(2) global [2 x { i32, ptr addrspace(1), ptr }] [{ i32, ptr addrspace(1), ptr } { i32 0, ptr addrspace(1) @existing_ctor, ptr null }, { i32, ptr addrspace(1), ptr } { i32 10, ptr addrspace(1) [[TABLE_CTOR:@[0-9]+]], ptr null }] -@llvm.global_ctors = appending global [1 x { i32, ptr addrspace(1), ptr }] [{ i32, ptr addrspace(1), ptr } { i32 0, ptr addrspace(1) @existing_ctor, ptr null }] +@llvm.global_ctors = appending addrspace(2) global [1 x { i32, ptr addrspace(1), ptr }] [{ i32, ptr addrspace(1), ptr } { i32 0, ptr addrspace(1) @existing_ctor, ptr null }]