Skip to content

Commit

Permalink
[ModuleUtils] Handle globals_ctors/dtors with non-literal type (PR56809)
Browse files Browse the repository at this point in the history
If the global already exists, use its existing type, so we don't
try to mix literal and non-literal structs among the elements.

Fixes #56809.
  • Loading branch information
nikic committed Mar 21, 2023
1 parent 514e435 commit b430743
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
10 changes: 6 additions & 4 deletions llvm/lib/Transforms/Utils/ModuleUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,20 @@ static void appendToGlobalArray(StringRef ArrayName, Module &M, Function *F,
// Get the current set of static global constructors and add the new ctor
// to the list.
SmallVector<Constant *, 16> CurrentCtors;
StructType *EltTy = StructType::get(
IRB.getInt32Ty(), PointerType::get(FnTy, F->getAddressSpace()),
IRB.getInt8PtrTy());

StructType *EltTy;
if (GlobalVariable *GVCtor = M.getNamedGlobal(ArrayName)) {
EltTy = cast<StructType>(GVCtor->getValueType()->getArrayElementType());
if (Constant *Init = GVCtor->getInitializer()) {
unsigned n = Init->getNumOperands();
CurrentCtors.reserve(n + 1);
for (unsigned i = 0; i != n; ++i)
CurrentCtors.push_back(cast<Constant>(Init->getOperand(i)));
}
GVCtor->eraseFromParent();
} else {
EltTy = StructType::get(
IRB.getInt32Ty(), PointerType::get(FnTy, F->getAddressSpace()),
IRB.getInt8PtrTy());
}

// Build a 3 field global_ctor entry. We don't take a comdat key.
Expand Down
36 changes: 36 additions & 0 deletions llvm/test/Transforms/LowerGlobalDestructors/non-literal-type.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals --include-generated-funcs --version 2
; RUN: opt -passes=lower-global-dtors -S < %s | FileCheck %s

%ty = type { i32, ptr, ptr }

declare void @ctor()
declare void @dtor()

@llvm.global_ctors = appending global [1 x %ty] [%ty {i32 65535, ptr @ctor, ptr zeroinitializer }], align 8
@llvm.global_dtors = appending global [1 x %ty] [%ty {i32 65535, ptr @dtor, ptr zeroinitializer }], align 8

;.
; CHECK: @[[__DSO_HANDLE:[a-zA-Z0-9_$"\\.-]+]] = extern_weak hidden constant i8
; CHECK: @[[LLVM_GLOBAL_CTORS:[a-zA-Z0-9_$"\\.-]+]] = appending global [2 x %ty] [[[TY:%.*]] { i32 65535, ptr @ctor, ptr null }, [[TY]] { i32 65535, ptr @register_call_dtors, ptr null }]
;.
; CHECK-LABEL: define private void @call_dtors
; CHECK-SAME: (ptr [[TMP0:%.*]]) {
; CHECK-NEXT: body:
; CHECK-NEXT: call void @dtor()
; CHECK-NEXT: ret void
;
;
; CHECK-LABEL: define private void @register_call_dtors() {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL:%.*]] = call i32 @__cxa_atexit(ptr @call_dtors, ptr null, ptr @__dso_handle)
; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i32 [[CALL]], 0
; CHECK-NEXT: br i1 [[TMP0]], label [[FAIL:%.*]], label [[RETURN:%.*]]
; CHECK: fail:
; CHECK-NEXT: call void @llvm.trap()
; CHECK-NEXT: unreachable
; CHECK: return:
; CHECK-NEXT: ret void
;
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { cold noreturn nounwind }
;.

0 comments on commit b430743

Please sign in to comment.