From 067c035012fc061ad6378458774ac2df117283c6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 10 Mar 2022 16:01:09 +0100 Subject: [PATCH] [GlobalOpt] Handle undef global_ctors gracefully If there are no ctors, then this can have an arbirary zero-sized value. The current code checks for null, but it could also be undef or poison. Replacing the specific null check with a check for non-ConstantArray. --- llvm/lib/Transforms/Utils/CtorUtils.cpp | 10 +++++----- llvm/test/Transforms/GlobalOpt/undef-ctor-dtor.ll | 9 +++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 llvm/test/Transforms/GlobalOpt/undef-ctor-dtor.ll diff --git a/llvm/lib/Transforms/Utils/CtorUtils.cpp b/llvm/lib/Transforms/Utils/CtorUtils.cpp index 069a86f..38bcce2 100644 --- a/llvm/lib/Transforms/Utils/CtorUtils.cpp +++ b/llvm/lib/Transforms/Utils/CtorUtils.cpp @@ -63,8 +63,6 @@ static void removeGlobalCtors(GlobalVariable *GCL, const BitVector &CtorsToRemov /// Given a llvm.global_ctors list that we can understand, /// return a list of the functions and null terminator as a vector. static std::vector parseGlobalCtors(GlobalVariable *GV) { - if (GV->getInitializer()->isNullValue()) - return std::vector(); ConstantArray *CA = cast(GV->getInitializer()); std::vector Result; Result.reserve(CA->getNumOperands()); @@ -87,9 +85,11 @@ static GlobalVariable *findGlobalCtors(Module &M) { if (!GV->hasUniqueInitializer()) return nullptr; - if (isa(GV->getInitializer())) - return GV; - ConstantArray *CA = cast(GV->getInitializer()); + // If there are no ctors, then the initializer might be null/undef/poison. + // Ignore anything but an array. + ConstantArray *CA = dyn_cast(GV->getInitializer()); + if (!CA) + return nullptr; for (auto &V : CA->operands()) { if (isa(V)) diff --git a/llvm/test/Transforms/GlobalOpt/undef-ctor-dtor.ll b/llvm/test/Transforms/GlobalOpt/undef-ctor-dtor.ll new file mode 100644 index 0000000..d77a5cd --- /dev/null +++ b/llvm/test/Transforms/GlobalOpt/undef-ctor-dtor.ll @@ -0,0 +1,9 @@ +; RUN: opt -S -globalopt < %s | FileCheck %s + +; Gracefully handle undef global_ctors/global_dtors + +; CHECK: @llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] undef +; CHECK: @llvm.global_dtors = appending global [0 x { i32, void ()*, i8* }] undef + +@llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] undef +@llvm.global_dtors = appending global [0 x { i32, void ()*, i8* }] undef -- 2.7.4