diff --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp index 6d17a466957e4..adc2fc0610f3b 100644 --- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp +++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp @@ -31,11 +31,9 @@ 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 CurrentCtors; - StructType *EltTy = StructType::get( - IRB.getInt32Ty(), PointerType::get(FnTy, F->getAddressSpace()), - IRB.getInt8PtrTy()); - + StructType *EltTy; if (GlobalVariable *GVCtor = M.getNamedGlobal(ArrayName)) { + EltTy = cast(GVCtor->getValueType()->getArrayElementType()); if (Constant *Init = GVCtor->getInitializer()) { unsigned n = Init->getNumOperands(); CurrentCtors.reserve(n + 1); @@ -43,6 +41,10 @@ static void appendToGlobalArray(StringRef ArrayName, Module &M, Function *F, CurrentCtors.push_back(cast(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. diff --git a/llvm/test/Transforms/LowerGlobalDestructors/non-literal-type.ll b/llvm/test/Transforms/LowerGlobalDestructors/non-literal-type.ll new file mode 100644 index 0000000000000..38f72e7ac70e5 --- /dev/null +++ b/llvm/test/Transforms/LowerGlobalDestructors/non-literal-type.ll @@ -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 } +;.