From 4e65291837aa33d1849a1ebe560ac816aabade39 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks Date: Wed, 27 Apr 2022 13:44:50 -0700 Subject: [PATCH] [OpaquePtr][GlobalOpt] Don't attempt to evaluate global constructors with arguments Previously all entries in global_ctors had to have the void()* type and we'd skip evaluating bitcasted functions. With opaque pointers we may see the function directly. Fixes #55147. Reviewed By: #opaque-pointers, nikic Differential Revision: https://reviews.llvm.org/D124553 --- llvm/lib/Transforms/Utils/CtorUtils.cpp | 5 +++-- llvm/lib/Transforms/Utils/Evaluator.cpp | 2 ++ .../Transforms/GlobalOpt/global-constructor-opaque-ptr.ll | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 llvm/test/Transforms/GlobalOpt/global-constructor-opaque-ptr.ll diff --git a/llvm/lib/Transforms/Utils/CtorUtils.cpp b/llvm/lib/Transforms/Utils/CtorUtils.cpp index 38bcce2..f8afcbd 100644 --- a/llvm/lib/Transforms/Utils/CtorUtils.cpp +++ b/llvm/lib/Transforms/Utils/CtorUtils.cpp @@ -98,8 +98,9 @@ static GlobalVariable *findGlobalCtors(Module &M) { if (isa(CS->getOperand(1))) continue; - // Must have a function or null ptr. - if (!isa(CS->getOperand(1))) + // Can only handle global constructors with no arguments. + Function *F = dyn_cast(CS->getOperand(1)); + if (!F || F->arg_size() != 0) return nullptr; // Init priority must be standard. diff --git a/llvm/lib/Transforms/Utils/Evaluator.cpp b/llvm/lib/Transforms/Utils/Evaluator.cpp index 0b1bc32..70b5e0e 100644 --- a/llvm/lib/Transforms/Utils/Evaluator.cpp +++ b/llvm/lib/Transforms/Utils/Evaluator.cpp @@ -629,6 +629,8 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB, /// function. bool Evaluator::EvaluateFunction(Function *F, Constant *&RetVal, const SmallVectorImpl &ActualArgs) { + assert(ActualArgs.size() == F->arg_size() && "wrong number of arguments"); + // Check to see if this function is already executing (recursion). If so, // bail out. TODO: we might want to accept limited recursion. if (is_contained(CallStack, F)) diff --git a/llvm/test/Transforms/GlobalOpt/global-constructor-opaque-ptr.ll b/llvm/test/Transforms/GlobalOpt/global-constructor-opaque-ptr.ll new file mode 100644 index 0000000..4ea91d1 --- /dev/null +++ b/llvm/test/Transforms/GlobalOpt/global-constructor-opaque-ptr.ll @@ -0,0 +1,14 @@ +; RUN: opt -passes=globalopt -S < %s | FileCheck %s + +; CHECK: @f1 +; CHECK: @f2 + +@llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @f1, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @f2, ptr null }] + +define void @f1(i32 %args) { + ret void +} + +define i32 @f2(i32 %args) { + ret i32 0 +} -- 2.7.4