Bug type: crash
Component: Evaluator
Bug location: llvm/include/llvm/Transforms/Utils/Evaluator.h: setVal
llvm/lib/Transforms/Utils/Evaluator.cpp: Evaluator::EvaluateBlock
Evaluator::castCallResultIfNeeded
Evaluator::getFormalParams
Issue title: SIGSEGV with -flto
Labels: incomplete
crash
LTO
Reported by: illiminable

Static linking with -flto on Arch linux with clang 18.1.8

Not able to get a minimal repro at the moment. Other possibly less common options

      "-std=c++20",
      "-nostdlib",
      "-nostartfiles",
      "-fno-exceptions",
      "-fno-rtti",

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007ee06170e69c in llvm::ConstantFoldConstant(llvm::Constant const*, llvm::DataLayout const&, llvm::TargetLibraryInfo const*) () from /usr/lib/libLLVM.so.18.1
#0  0x00007ee06170e69c in llvm::ConstantFoldConstant(llvm::Constant const*, llvm::DataLayout const&, llvm::TargetLibraryInfo const*) () from /usr/lib/libLLVM.so.18.1
#1  0x00007ee060abea1a in llvm::Evaluator::EvaluateBlock(llvm::ilist_iterator_w_bits<llvm::ilist_detail::node_options<llvm::Instruction, false, false, void, true>, false, false>, llvm::BasicBlock*&, bool&) () from /usr/lib/libLLVM.so.18.1
#2  0x00007ee060ac14e4 in llvm::Evaluator::EvaluateFunction(llvm::Function*, llvm::Constant*&, llvm::SmallVectorImpl<llvm::Constant*> const&) () from /usr/lib/libLLVM.so.18.1
#3  0x00007ee061307930 in ?? () from /usr/lib/libLLVM.so.18.1
#4  0x00007ee061308634 in ?? () from /usr/lib/libLLVM.so.18.1
#5  0x00007ee060aa7649 in llvm::optimizeGlobalCtorsList(llvm::Module&, llvm::function_ref<bool (unsigned int, llvm::Function*)>) () from /usr/lib/libLLVM.so.18.1
#6  0x00007ee0613135f9 in llvm::GlobalOptPass::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) () from /usr/lib/libLLVM.so.18.1
#7  0x00007ee06411d177 in ?? () from /usr/lib/libLLVM.so.18.1
#8  0x00007ee05fbd767e in llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) () from /usr/lib/libLLVM.so.18.1
#9  0x00007ee061a57995 in ?? () from /usr/lib/libLLVM.so.18.1
#10 0x00007ee061a591ff in llvm::lto::opt(llvm::lto::Config const&, llvm::TargetMachine*, unsigned int, llvm::Module&, bool, llvm::ModuleSummaryIndex*, llvm::ModuleSummaryIndex const*, std::vector<unsigned char, std::allocator<unsigned char> > const&) () from /usr/lib/libLLVM.so.18.1
#11 0x00007ee061a5a582 in llvm::lto::backend(llvm::lto::Config const&, std::function<llvm::Expected<std::unique_ptr<llvm::CachedFileStream, std::default_delete<llvm::CachedFileStream> > > (unsigned int, llvm::Twine const&)>, unsigned int, llvm::Module&, llvm::ModuleSummaryIndex&) () from /usr/lib/libLLVM.so.18.1
#12 0x00007ee061a4ed49 in llvm::lto::LTO::runRegularLTO(std::function<llvm::Expected<std::unique_ptr<llvm::CachedFileStream, std::default_delete<llvm::CachedFileStream> > > (unsigned int, llvm::Twine const&)>) () from /usr/lib/libLLVM.so.18.1
#13 0x00007ee061a4f241 in llvm::lto::LTO::run(std::function<llvm::Expected<std::unique_ptr<llvm::CachedFileStream, std::default_delete<llvm::CachedFileStream> > > (unsigned int, llvm::Twine const&)>, std::function<llvm::Expected<std::function<llvm::Expected<std::unique_ptr<llvm::CachedFileStream, std::default_delete<llvm::CachedFileStream> > > (unsigned int, llvm::Twine const&)> > (unsigned int, llvm::StringRef, llvm::Twine const&)>) () from /usr/lib/libLLVM.so.18.1
#14 0x00007ee0678ce067 in ?? () from /usr/bin/../lib/LLVMgold.so
#15 0x00007ee0678cfd12 in ?? () from /usr/bin/../lib/LLVMgold.so
#16 0x000056f827567837 in ?? ()
#17 0x000056f82756f75f in ?? ()
#18 0x00007ee067a00e08 in ?? () from /usr/lib/libc.so.6
#19 0x00007ee067a00ecc in __libc_start_main () from /usr/lib/libc.so.6
#20 0x000056f82756ea65 in ?? ()


Comments: author: EugeneZelenko
body: Could you please try 19 or `main` branch?
author: illiminable
body: I don't think 19 is packaged for arch yet. I'll see if I can build trunk later in the week.

Is it possible to just to disable this optimizeGlobalCtorsList or all of globalopt. I looked through --hidden-help and could not see an option like this.
author: ms178
body: @illiminable While it is not packaged by Arch yet, you could try the linked toolchain instead and use it via an environment variable which points llvm to the new path: https://mirrors.edge.kernel.org/pub/tools/llvm/
author: illiminable
body: OK thanks I'll try. FWIW this is the approximate code pattern. And presumably its trying to optimize the fact that there are N unique symbols that "register" assigns true to but then never get used.

```
// Header File
class Functor {
   virtual void execImpl() = 0;
   void exec() { execImpl(); }
 };
 
 class Info {
   Functor* fn = nullptr;
 };
 
 class Registry {
   array<Info, 1024> fns;
   int count = 0;
   
   void register(Info&& f) {
     fns[count++] = f;
   }
   
   void exec() {
      for i in 0..count { fns[i].fn->exec(); }
   }
 };
 
 inline Registry reg;
 
 inline bool register(Functor* fn) {
   reg.register({.fn = fn});
   return true;
 }
 
 
 // REPEAT approx 10 each copies of the below in 10 different .cpp TU's
 class _uniquesymbol_ : public Functor {
   void execImpl() override;
 };
 
 // Instance of the derived functor class
 _uniquesymbol_ _uniquesymbol__instance;
 
 // _uniquesymbol__flag is always true and never used. Theres probably a better
 // way to do this?
 const bool _uniquesymbol__flag = register(&_uniquesymbol__instance);
 
 void _uniquesymbol_::execImpl() {
   // do stuff
 }
 
 // END REPEAT
 
 
 // Usage...
 reg.exec();
``` 

author: illiminable
body: @ms178 The toolchain didn't work because it doesn't contain LLVMgold.so

I was able to build from the 19.1.5 branch in debug and can repro. It's only on one target. This is the assert output

ld.gold: /mnt/local/src/third_party/github/llvm/llvm-project/llvm/include/llvm/Support/Casting.h:109: static bool llvm::isa_impl_cl<To, const From*>::doit(const From*) [with To = llvm::ConstantVector; From = llvm::Constant]: Assertion `Val && "isa<> used on a null pointer"' failed.

And a better symbolized stack

#0  0x00007c11cae473f4 in ?? () from /usr/lib/libc.so.6
#0  0x00007c11cae473f4 in ?? () from /usr/lib/libc.so.6
#1  0x00007c11cadee120 in raise () from /usr/lib/libc.so.6
#2  0x00007c11cadd54c3 in abort () from /usr/lib/libc.so.6
#3  0x00007c11cadd53df in ?? () from /usr/lib/libc.so.6
#4  0x00007c11cade6177 in __assert_fail () from /usr/lib/libc.so.6
#5  0x00007c11c329c245 in llvm::isa_impl_cl<llvm::ConstantVector, llvm::Constant const*>::doit (Val=0x0) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/include/llvm/Support/Casting.h:109
#6  0x00007c11c329bd99 in llvm::isa_impl_wrap<llvm::ConstantVector, llvm::Constant const*, llvm::Constant const*>::doit (Val=@0x7ffd009f71a0: 0x0) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/include/llvm/Support/Casting.h:137
#7  0x00007c11c329b45b in llvm::isa_impl_wrap<llvm::ConstantVector, llvm::Constant const* const, llvm::Constant const*>::doit (Val=@0x7ffd009f71f0: 0x0) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/include/llvm/Support/Casting.h:129
#8  0x00007c11c329a6b6 in llvm::CastIsPossible<llvm::ConstantVector, llvm::Constant const*, void>::isPossible (f=@0x7ffd009f71f0: 0x0) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/include/llvm/Support/Casting.h:257
#9  0x00007c11c5ccd903 in llvm::CastInfo<llvm::ConstantVector, llvm::Constant const* const, void>::isPossible (f=@0x7ffd009f7248: 0x0) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/include/llvm/Support/Casting.h:509
#10 0x00007c11c5ccd3d8 in llvm::isa<llvm::ConstantVector, llvm::Constant const*> (Val=@0x7ffd009f7248: 0x0) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/include/llvm/Support/Casting.h:549
#11 0x00007c11c5f8be6e in (anonymous namespace)::ConstantFoldConstantImpl (C=0x0, DL=..., TLI=0x5d4a86076c38, FoldedOps=...) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/lib/Analysis/ConstantFolding.cpp:1078
#12 0x00007c11c5f8c5d3 in llvm::ConstantFoldConstant (C=0x0, DL=..., TLI=0x5d4a86076c38) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/lib/Analysis/ConstantFolding.cpp:1163
#13 0x00007c11c5cb7bdc in llvm::Evaluator::EvaluateBlock (this=0x7ffd009f7930, CurInst=..., NextBB=@0x7ffd009f76e0: 0x0, StrippedPointerCastsForAliasAnalysis=@0x7ffd009f76d0: false) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/lib/Transforms/Utils/Evaluator.cpp:610
#14 0x00007c11c5cb7fd8 in llvm::Evaluator::EvaluateFunction (this=0x7ffd009f7930, F=0x5d4a85ccc618, RetVal=@0x7ffd009f78a8: 0x7ffd009f7ae0, ActualArgs=...) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/lib/Transforms/Utils/Evaluator.cpp:660
#15 0x00007c11c4f410a8 in EvaluateStaticConstructor (F=0x5d4a85ccc618, DL=..., TLI=0x5d4a86076c38) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/lib/Transforms/IPO/GlobalOpt.cpp:2080
#16 0x00007c11c4f42bf7 in operator() (__closure=0x7ffd009f7e90, Priority=65535, F=0x5d4a85ccc618) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/lib/Transforms/IPO/GlobalOpt.cpp:2524
#17 0x00007c11c4f43f3b in llvm::function_ref<bool(unsigned int, llvm::Function*)>::callback_fn<optimizeGlobalsInModule(llvm::Module&, const llvm::DataLayout&, llvm::function_ref<llvm::TargetLibraryInfo&(llvm::Function&)>, llvm::function_ref<llvm::TargetTransformInfo&(llvm::Function&)>, llvm::function_ref<llvm::BlockFrequencyInfo&(llvm::Function&)>, llvm::function_ref<llvm::DominatorTree&(llvm::Function&)>, llvm::function_ref<void(llvm::Function&)>, llvm::function_ref<void(llvm::Function&)>)::<lambda(uint32_t, llvm::Function*)> >(intptr_t, unsigned int, llvm::Function *) (callable=140724613906064, params#0=65535, params#1=0x5d4a85ccc618) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/include/llvm/ADT/STLFunctionalExtras.h:45
#18 0x00007c11c5c95103 in llvm::function_ref<bool(unsigned int, llvm::Function*)>::operator() (this=0x7ffd009f7cc0, params#0=65535, params#1=0x5d4a85ccc618) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/include/llvm/ADT/STLFunctionalExtras.h:68
#19 0x00007c11c5c92754 in llvm::optimizeGlobalCtorsList (M=..., ShouldRemove=...) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/lib/Transforms/Utils/CtorUtils.cpp:138
#20 0x00007c11c4f4309c in optimizeGlobalsInModule(llvm::Module &, const llvm::DataLayout &, llvm::function_ref<llvm::TargetLibraryInfo&(llvm::Function&)>, llvm::function_ref<llvm::TargetTransformInfo&(llvm::Function&)>, llvm::function_ref<llvm::BlockFrequencyInfo&(llvm::Function&)>, llvm::function_ref<llvm::DominatorTree&(llvm::Function&)>, llvm::function_ref<void(llvm::Function&)>, llvm::function_ref<void(llvm::Function&)>) (M=..., DL=..., GetTLI=..., GetTTI=..., GetBFI=..., LookupDomTree=..., ChangedCFGCallback=..., DeleteFnCallback=...) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/lib/Transforms/IPO/GlobalOpt.cpp:2520
#21 0x00007c11c4f435e0 in llvm::GlobalOptPass::run (this=0x5d4a85c13138, M=..., AM=...) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/lib/Transforms/IPO/GlobalOpt.cpp:2583
#22 0x00007c11c4366477 in llvm::detail::PassModel<llvm::Module, llvm::GlobalOptPass, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (this=0x5d4a85c13130, IR=..., AM=...) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:90
#23 0x00007c11c6e2f349 in llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (this=0x7ffd009f8300, IR=..., AM=...) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h:81
#24 0x00007c11c3934968 in runNewPMPasses (Conf=..., Mod=..., TM=0x5d4a85edf0b0, OptLevel=3, IsThinLTO=false, ExportSummary=0x5d4a85bc6d18, ImportSummary=0x0) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/lib/LTO/LTOBackend.cpp:338
#25 0x00007c11c3934b94 in llvm::lto::opt (Conf=..., TM=0x5d4a85edf0b0, Task=0, Mod=..., IsThinLTO=false, ExportSummary=0x5d4a85bc6d18, ImportSummary=0x0, CmdArgs=std::vector of length 0, capacity 0) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/lib/LTO/LTOBackend.cpp:363
#26 0x00007c11c3936054 in llvm::lto::backend (C=..., AddStream=..., ParallelCodeGenParallelismLevel=1, Mod=..., CombinedIndex=...) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/lib/LTO/LTOBackend.cpp:517
#27 0x00007c11c38e855d in llvm::lto::LTO::runRegularLTO (this=0x5d4a85bc6710, AddStream=...) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/lib/LTO/LTO.cpp:1354
#28 0x00007c11c38e746b in llvm::lto::LTO::run (this=0x5d4a85bc6710, AddStream=..., Cache=...) at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/lib/LTO/LTO.cpp:1186
#29 0x00007c11c3255536 in runLTO () at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/tools/gold/gold-plugin.cpp:1111
#30 0x00007c11c3255a0d in allSymbolsReadHook () at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/tools/gold/gold-plugin.cpp:1148
#31 0x00007c11c3255c19 in all_symbols_read_hook () at /mnt/local/src/third_party/github/llvm/llvm-project/llvm/tools/gold/gold-plugin.cpp:1173
#32 0x00005d4a6c4d9154 in ?? ()
#33 0x00005d4a6c5138d0 in ?? ()
#34 0x00005d4a6c3fc49a in ?? ()
#35 0x00007c11cadd6e08 in ?? () from /usr/lib/libc.so.6
#36 0x00007c11cadd6ecc in __libc_start_main () from /usr/lib/libc.so.6
#37 0x00005d4a6c3ff985 in ?? ()
author: ms178
body: @illiminable Thanks for letting me know. Unfortunately I am not a developer and cannot help you to debug this problem further.
author: illiminable
body: I debugged a little bit, but I don't fully understand this code.

In EvaluateBlock the issue is that after the various branches the code falls out to this block at 609 with InstResult still null. All the other branches usually check InstResult and return false. ConstantFoldConstant will assert or crash if the  first parameter is null in the call from 610. I also tried just guarding this conditino with !InstResult but that doesn't seem right since it triggers another assert later "Assertion `R && "Reference to an uncomputed value!"'.

https://github.com/llvm/llvm-project/blob/llvmorg-19.1.5/llvm/lib/Transforms/Utils/Evaluator.cpp#L610

The bug only only occurs when the code hits the branch on 556. Strangely the debug log here says both branches of the if are success. I don't know if it's a copy paste error or if maybe the code should just return true after 558, but given the rest of the code this doesn't seem right.

But returning false in the line 556 branch seems to fix the crash and the resulting program seems to work fine.

https://github.com/llvm/llvm-project/blob/llvmorg-19.1.5/llvm/lib/Transforms/Utils/Evaluator.cpp#L556

Someone who understands the code better should evaluate though.

author: illiminable
body: I used llvm-reduce to reduce the bitcode and when i looked at what was left it was basically __cxa_guard_acquire and I realized that while bootstrapping i defined it with the wrong return type. So since I violated the ABI I guess my fault.

Not sure if there is still an underlying issue here someone wants to fix. ie. would be better to error or ignore than crash. But it seems pretty unlikely someone else will hit at least this specific cause of the problem.

Can probably close if this corner case is not important.
author: nikic
body: Could you please share the reduced bitcode? (Or IR after running it through llvm-dis.)
author: illiminable
body: [reduced.zip](https://github.com/user-attachments/files/18043521/reduced.zip)

This is the reduced.bc



Fix patch:
commit 5013c81b781eb95af8e429956d63c8f9c16a4647
Author: Nikita Popov <npopov@redhat.com>
Date:   Thu Dec 12 10:44:52 2024 +0100

    [GlobalOpt][Evaluator] Don't evaluate calls with signature mismatch (#119548)
    
    The global ctor evaluator tries to evalute function calls where the call
    function type and function type do not match, by performing bitcasts.
    This currently causes a crash when calling a void function with non-void
    return type.
    
    I've opted to remove this functionality entirely rather than fixing this
    specific case. With opaque pointers, there shouldn't be a legitimate use
    case for this anymore, as we don't need to look through pointer type
    casts. Doing other bitcasts is very iffy because it ignores ABI
    considerations. We should at least leave adjusting the signatures to
    make them line up to InstCombine (which also does some iffy things, but
    is at least somewhat more constrained).
    
    Fixes https://github.com/llvm/llvm-project/issues/118725.

diff --git a/llvm/include/llvm/Transforms/Utils/Evaluator.h b/llvm/include/llvm/Transforms/Utils/Evaluator.h
index 5d53773b5d6b..118037625421 100644
--- a/llvm/include/llvm/Transforms/Utils/Evaluator.h
+++ b/llvm/include/llvm/Transforms/Utils/Evaluator.h
@@ -125,9 +125,6 @@ private:
     ValueStack.back()[V] = C;
   }
 
-  /// Casts call result to a type of bitcast call expression
-  Constant *castCallResultIfNeeded(Type *ReturnType, Constant *RV);
-
   /// Given call site return callee and list of its formal arguments
   Function *getCalleeWithFormalArgs(CallBase &CB,
                                     SmallVectorImpl<Constant *> &Formals);
diff --git a/llvm/lib/Transforms/Utils/Evaluator.cpp b/llvm/lib/Transforms/Utils/Evaluator.cpp
index cf1a8b4af112..2af447aadce2 100644
--- a/llvm/lib/Transforms/Utils/Evaluator.cpp
+++ b/llvm/lib/Transforms/Utils/Evaluator.cpp
@@ -253,40 +253,17 @@ Evaluator::getCalleeWithFormalArgs(CallBase &CB,
 
 bool Evaluator::getFormalParams(CallBase &CB, Function *F,
                                 SmallVectorImpl<Constant *> &Formals) {
-  if (!F)
-    return false;
-
   auto *FTy = F->getFunctionType();
-  if (FTy->getNumParams() > CB.arg_size()) {
-    LLVM_DEBUG(dbgs() << "Too few arguments for function.\n");
+  if (FTy != CB.getFunctionType()) {
+    LLVM_DEBUG(dbgs() << "Signature mismatch.\n");
     return false;
   }
 
-  auto ArgI = CB.arg_begin();
-  for (Type *PTy : FTy->params()) {
-    auto *ArgC = ConstantFoldLoadThroughBitcast(getVal(*ArgI), PTy, DL);
-    if (!ArgC) {
-      LLVM_DEBUG(dbgs() << "Can not convert function argument.\n");
-      return false;
-    }
-    Formals.push_back(ArgC);
-    ++ArgI;
-  }
+  for (Value *Arg : CB.args())
+    Formals.push_back(getVal(Arg));
   return true;
 }
 
-/// If call expression contains bitcast then we may need to cast
-/// evaluated return value to a type of the call expression.
-Constant *Evaluator::castCallResultIfNeeded(Type *ReturnType, Constant *RV) {
-  if (!RV || RV->getType() == ReturnType)
-    return RV;
-
-  RV = ConstantFoldLoadThroughBitcast(RV, ReturnType, DL);
-  if (!RV)
-    LLVM_DEBUG(dbgs() << "Failed to fold bitcast call expr\n");
-  return RV;
-}
-
 /// Evaluate all instructions in block BB, returning true if successful, false
 /// if we can't evaluate it.  NewBB returns the next BB that control flows into,
 /// or null upon return. StrippedPointerCastsForAliasAnalysis is set to true if
@@ -520,9 +497,7 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB,
         if (Callee->isDeclaration()) {
           // If this is a function we can constant fold, do it.
           if (Constant *C = ConstantFoldCall(&CB, Callee, Formals, TLI)) {
-            InstResult = castCallResultIfNeeded(CB.getType(), C);
-            if (!InstResult)
-              return false;
+            InstResult = C;
             LLVM_DEBUG(dbgs() << "Constant folded function call. Result: "
                               << *InstResult << "\n");
           } else {
@@ -544,10 +519,7 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB,
             return false;
           }
           ValueStack.pop_back();
-          InstResult = castCallResultIfNeeded(CB.getType(), RetVal);
-          if (RetVal && !InstResult)
-            return false;
-
+          InstResult = RetVal;
           if (InstResult) {
             LLVM_DEBUG(dbgs() << "Successfully evaluated function. Result: "
                               << *InstResult << "\n\n");


Regression tests:
file: llvm/test/Transforms/GlobalOpt/evaluate-ret-void-mismatch.ll
commands: opt -S -passes=globalopt < %s
tests: test_name: <module>
test_body: 
; Don't evaluate call with return value type mismatch.

@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init, ptr null }]

define void @__cxa_guard_acquire() {
;
entry:
  ret void
}

define void @__cxx_global_var_init() {
;
  %res = call i32 @__cxa_guard_acquire()
  %tobool.not = icmp eq i32 %res, 0
  ret void
}