[OpaquePtr][GlobalOpt] Don't attempt to evaluate global constructors with arguments
authorArthur Eubanks <aeubanks@google.com>
Wed, 27 Apr 2022 20:44:50 +0000 (13:44 -0700)
committerArthur Eubanks <aeubanks@google.com>
Thu, 28 Apr 2022 02:00:44 +0000 (19:00 -0700)
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
llvm/lib/Transforms/Utils/Evaluator.cpp
llvm/test/Transforms/GlobalOpt/global-constructor-opaque-ptr.ll [new file with mode: 0644]

index 38bcce2..f8afcbd 100644 (file)
@@ -98,8 +98,9 @@ static GlobalVariable *findGlobalCtors(Module &M) {
     if (isa<ConstantPointerNull>(CS->getOperand(1)))
       continue;
 
-    // Must have a function or null ptr.
-    if (!isa<Function>(CS->getOperand(1)))
+    // Can only handle global constructors with no arguments.
+    Function *F = dyn_cast<Function>(CS->getOperand(1));
+    if (!F || F->arg_size() != 0)
       return nullptr;
 
     // Init priority must be standard.
index 0b1bc32..70b5e0e 100644 (file)
@@ -629,6 +629,8 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB,
 /// function.
 bool Evaluator::EvaluateFunction(Function *F, Constant *&RetVal,
                                  const SmallVectorImpl<Constant*> &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 (file)
index 0000000..4ea91d1
--- /dev/null
@@ -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
+}