Thanks, I'm able to reproduce it and have a fix I'm testing. Sorry for the breakage!!<br><br><div class="gmail_quote">On 24 July 2012 09:05, David Dean <span dir="ltr"><<a href="mailto:david_dean@apple.com" target="_blank">david_dean@apple.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Nick, this seems to be breaking self-hosting on darwin:<br>
<br>
While deleting: %"class.std::basic_string"* %temp.lvalue<br>
Use still stuck around after Def is destroyed:  call void @_ZNSsD1Ev(%"class.std::basic_string"* %temp.lvalue)<br>
Use still stuck around after Def is destroyed:  call void @_ZNK4llvm9StringRefcvSsEv(%"class.std::basic_string"* sret %temp.lvalue, %"class.llvm::StringRef"* %coerce)<br>
Assertion failed: (use_empty() && "Uses remain when a value is destroyed!"), function ~Value, file /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-nobootstrap-RA/llvm/lib/VMCore/Value.cpp, line 75.<br>


0  clang             0x000000010159a472 llvm::SmallVectorImpl<char>::swap(llvm::SmallVectorImpl<char>&) + 14450<br>
1  clang             0x000000010159a954 llvm::SmallVectorImpl<char>::swap(llvm::SmallVectorImpl<char>&) + 15700<br>
2  libsystem_c.dylib 0x00007fff9135fcfa _sigtramp + 26<br>
3  libsystem_c.dylib 0x0000000000000002 _sigtramp + 18446603338079929122<br>
4  clang             0x000000010159a6b6 llvm::SmallVectorImpl<char>::swap(llvm::SmallVectorImpl<char>&) + 15030<br>
5  clang             0x000000010159a691 llvm::SmallVectorImpl<char>::swap(llvm::SmallVectorImpl<char>&) + 14993<br>
6  clang             0x000000010154d44d llvm::enable_if<llvm::hashing::detail::is_hashable_data<llvm::Type* const>, llvm::hash_code>::type llvm::hashing::detail::hash_combine_range_impl<llvm::Type* const>(llvm::Type* const*, llvm::Type* const*) + 7101<br>


7  clang             0x000000010151b20e std::_Rb_tree<std::pair<llvm::PointerType*, llvm::InlineAsmKeyType>, std::pair<std::pair<llvm::PointerType*, llvm::InlineAsmKeyType> const, llvm::InlineAsm*>, std::_Select1st<std::pair<std::pair<llvm::PointerType*, llvm::InlineAsmKeyType> const, llvm::InlineAsm*> >, std::less<std::pair<llvm::PointerType*, llvm::InlineAsmKeyType> >, std::allocator<std::pair<std::pair<llvm::PointerType*, llvm::InlineAsmKeyType> const, llvm::InlineAsm*> > >::_M_insert_unique(std::pair<std::pair<llvm::PointerType*, llvm::InlineAsmKeyType> const, llvm::InlineAsm*> const&) + 21246<br>


8  clang             0x0000000100ad9e54 std::vector<llvm::Function*, std::allocator<llvm::Function*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<llvm::Function**, std::vector<llvm::Function*, std::allocator<llvm::Function*> > >, llvm::Function* const&) + 20532<br>


9  clang             0x0000000100ad7506 std::vector<llvm::Function*, std::allocator<llvm::Function*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<llvm::Function**, std::vector<llvm::Function*, std::allocator<llvm::Function*> > >, llvm::Function* const&) + 9958<br>


10 clang             0x0000000100ad5c26 std::vector<llvm::Function*, std::allocator<llvm::Function*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<llvm::Function**, std::vector<llvm::Function*, std::allocator<llvm::Function*> > >, llvm::Function* const&) + 3590<br>


11 clang             0x000000010153d646 std::vector<llvm::StructType*, std::allocator<llvm::StructType*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<llvm::StructType**, std::vector<llvm::StructType*, std::allocator<llvm::StructType*> > >, llvm::StructType* const&) + 31510<br>


12 clang             0x000000010153dc09 std::vector<llvm::StructType*, std::allocator<llvm::StructType*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<llvm::StructType**, std::vector<llvm::StructType*, std::allocator<llvm::StructType*> > >, llvm::StructType* const&) + 32985<br>


13 clang             0x000000010153dded std::vector<llvm::StructType*, std::allocator<llvm::StructType*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<llvm::StructType**, std::vector<llvm::StructType*, std::allocator<llvm::StructType*> > >, llvm::StructType* const&) + 33469<br>


14 clang             0x000000010016256a std::vector<clang::serialization::ModuleFile*, std::allocator<clang::serialization::ModuleFile*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<clang::serialization::ModuleFile**, std::vector<clang::serialization::ModuleFile*, std::allocator<clang::serialization::ModuleFile*> > >, clang::serialization::ModuleFile* const&) + 7738<br>


15 clang             0x0000000100244dca llvm::ParseIR(llvm::MemoryBuffer*, llvm::SMDiagnostic&, llvm::LLVMContext&) + 2010<br>
16 clang             0x000000010027b9b4 std::vector<std::pair<llvm::WeakVH, llvm::Constant*>, std::allocator<std::pair<llvm::WeakVH, llvm::Constant*> > >::_M_insert_aux(__gnu_cxx::__normal_iterator<std::pair<llvm::WeakVH, llvm::Constant*>*, std::vector<std::pair<llvm::WeakVH, llvm::Constant*>, std::allocator<std::pair<llvm::WeakVH, llvm::Constant*> > > >, std::pair<llvm::WeakVH, llvm::Constant*> const&) + 53524<br>


17 clang             0x0000000100243a00 std::vector<clang::CXXRecordDecl const*, std::allocator<clang::CXXRecordDecl const*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<clang::CXXRecordDecl const**, std::vector<clang::CXXRecordDecl const*, std::allocator<clang::CXXRecordDecl const*> > >, clang::CXXRecordDecl const* const&) + 6224<br>


18 clang             0x000000010004f0b8 llvm::SmallVectorImpl<clang::FileEntry const*>::operator=(llvm::SmallVectorImpl<clang::FileEntry const*> const&) + 10184<br>
19 clang             0x0000000100024d5f std::vector<clang::CompilerInstance*, std::allocator<clang::CompilerInstance*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<clang::CompilerInstance**, std::vector<clang::CompilerInstance*, std::allocator<clang::CompilerInstance*> > >, clang::CompilerInstance* const&) + 16623<br>


20 clang             0x000000010000b40a std::_Rb_tree<std::string, std::string, std::_Identity<std::string>, std::less<std::string>, std::allocator<std::string> >::_M_insert_unique(std::string const&) + 3978<br>


21 clang             0x0000000100000e1a<br>
22 clang             0x0000000100007e6c std::vector<std::string, std::allocator<std::string> >::_M_insert_aux(__gnu_cxx::__normal_iterator<std::string*, std::vector<std::string, std::allocator<std::string> > >, std::string const&) + 4124<br>


23 clang             0x0000000100000b34<br>
24 clang             0x000000000000004f<br>
Stack dump:<br>
0.      Program arguments: /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-RA/host-compiler/bin/clang -cc1 -triple x86_64-apple-macosx10.7.0 -emit-obj -disable-free -main-file-name PrettyStackTrace.cpp -pic-level 2 -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 127.2.1 -coverage-file /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-RA/clang-build/lib/Support/Release+Asserts/PrettyStackTrace.o -resource-dir /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-RA/host-compiler/bin/../lib/clang/3.2 -dependency-file /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-RA/clang-build/lib/Support/Release+Asserts/PrettyStackTrace.d.tmp -MP -MT /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-RA/clang-build/lib/Support/Release+Asserts/PrettyStackTrace.o -MT /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-RA/clang-build/lib/Support/Release+Asserts/PrettyStackTrace.d -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-RA/clang-build/include -I /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-RA/clang-build/lib/Support -I /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-RA/llvm/include -I /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-RA/llvm/lib/Support -fmodule-cache-path /var/folders/c0/p42p46x90pz38sc3mpntqhh80000gp/T/clang-module-cache -O3 -Woverloaded-virtual -Wcast-qual -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcovered-switch-default -fconst-strings -fdeprecated-macro -fdebug-compilation-dir /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-RA/clang-build/lib/Support -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.7.0 -fobjc-dispatch-method=mixed -fobjc-default-synthesize-properties -fno-common -fdiagnostics-show-option -o /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-RA/clang-build/lib/Support/Release+Asserts/PrettyStackTrace.o -x c++ /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-RA/llvm/lib/Support/PrettyStackTrace.cpp<br>


1.      <eof> parser at end of file<br>
2.      Per-module optimization passes<br>
3.      Running pass 'Global Variable Optimizer' on module '/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-RA/llvm/lib/Support/PrettyStackTrace.cpp'.<br>
clang: error: unable to execute command: Illegal instruction: 4<br>
clang: error: clang frontend command failed due to signal (use -v to see invocation)<br>
clang version 3.2 (trunk 160664)<br>
<br>
<br>
I've attached the preprocessed source and run script to reproduce.<br>
<br>
<br><br>
<br>
On 24 Jul 2012, at 12:21 AM, Nick Lewycky <<a href="mailto:nicholas@mxc.ca">nicholas@mxc.ca</a>> wrote:<br>
<br>
> Author: nicholas<br>
> Date: Tue Jul 24 02:21:08 2012<br>
> New Revision: 160664<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=160664&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=160664&view=rev</a><br>
> Log:<br>
> Teach globalopt to not nuke all stores to globals. Keep them around of they<br>
> might be deliberate "one time" leaks, so that leak checkers can find them.<br>
> This is a reapply of r160602 with the fix that this time I'm committing the<br>
> code I thought I was committing last time; the I->eraseFromParent() goes<br>
> *after* the break out of the loop.<br>
><br>
> Added:<br>
>    llvm/trunk/test/Transforms/GlobalOpt/cleanup-pointer-root-users.ll<br>
> Modified:<br>
>    llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp<br>
>    llvm/trunk/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll<br>
><br>
> Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=160664&r1=160663&r2=160664&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=160664&r1=160663&r2=160664&view=diff</a><br>


> ==============================================================================<br>
> --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)<br>
> +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Tue Jul 24 02:21:08 2012<br>
> @@ -296,6 +296,165 @@<br>
>   return false;<br>
> }<br>
><br>
> +/// isLeakCheckerRoot - Is this global variable possibly used by a leak checker<br>
> +/// as a root?  If so, we might not really want to eliminate the stores to it.<br>
> +static bool isLeakCheckerRoot(GlobalVariable *GV) {<br>
> +  // A global variable is a root if it is a pointer, or could plausibly contain<br>
> +  // a pointer.  There are two challenges; one is that we could have a struct<br>
> +  // the has an inner member which is a pointer.  We recurse through the type to<br>
> +  // detect these (up to a point).  The other is that we may actually be a union<br>
> +  // of a pointer and another type, and so our LLVM type is an integer which<br>
> +  // gets converted into a pointer, or our type is an [i8 x #] with a pointer<br>
> +  // potentially contained here.<br>
> +<br>
> +  if (GV->hasPrivateLinkage())<br>
> +    return false;<br>
> +<br>
> +  SmallVector<Type *, 4> Types;<br>
> +  Types.push_back(cast<PointerType>(GV->getType())->getElementType());<br>
> +<br>
> +  unsigned Limit = 20;<br>
> +  do {<br>
> +    Type *Ty = Types.pop_back_val();<br>
> +    switch (Ty->getTypeID()) {<br>
> +      default: break;<br>
> +      case Type::PointerTyID: return true;<br>
> +      case Type::ArrayTyID:<br>
> +      case Type::VectorTyID: {<br>
> +        SequentialType *STy = cast<SequentialType>(Ty);<br>
> +        Types.push_back(STy->getElementType());<br>
> +        break;<br>
> +      }<br>
> +      case Type::StructTyID: {<br>
> +        StructType *STy = cast<StructType>(Ty);<br>
> +        if (STy->isOpaque()) return true;<br>
> +        for (StructType::element_iterator I = STy->element_begin(),<br>
> +                 E = STy->element_end(); I != E; ++I) {<br>
> +          Type *InnerTy = *I;<br>
> +          if (isa<PointerType>(InnerTy)) return true;<br>
> +          if (isa<CompositeType>(InnerTy))<br>
> +            Types.push_back(InnerTy);<br>
> +        }<br>
> +        break;<br>
> +      }<br>
> +    }<br>
> +    if (--Limit == 0) return true;<br>
> +  } while (!Types.empty());<br>
> +  return false;<br>
> +}<br>
> +<br>
> +/// Given a value that is stored to a global but never read, determine whether<br>
> +/// it's safe to remove the store and the chain of computation that feeds the<br>
> +/// store.<br>
> +static bool IsSafeComputationToRemove(Value *V) {<br>
> +  do {<br>
> +    if (isa<Constant>(V))<br>
> +      return true;<br>
> +    if (!V->hasOneUse())<br>
> +      return false;<br>
> +    if (isa<LoadInst>(V) || isa<Argument>(V) || isa<GlobalValue>(V))<br>
> +      return false;<br>
> +    if (isAllocationFn(V))<br>
> +      return true;<br>
> +<br>
> +    Instruction *I = cast<Instruction>(V);<br>
> +    if (I->mayHaveSideEffects())<br>
> +      return false;<br>
> +    if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(I)) {<br>
> +      if (!GEP->hasAllConstantIndices())<br>
> +        return false;<br>
> +    } else if (I->getNumOperands() != 1) {<br>
> +      return false;<br>
> +    }<br>
> +<br>
> +    V = I->getOperand(0);<br>
> +  } while (1);<br>
> +}<br>
> +<br>
> +/// CleanupPointerRootUsers - This GV is a pointer root.  Loop over all users<br>
> +/// of the global and clean up any that obviously don't assign the global a<br>
> +/// value that isn't dynamically allocated.<br>
> +///<br>
> +static bool CleanupPointerRootUsers(GlobalVariable *GV) {<br>
> +  // A brief explanation of leak checkers.  The goal is to find bugs where<br>
> +  // pointers are forgotten, causing an accumulating growth in memory<br>
> +  // usage over time.  The common strategy for leak checkers is to whitelist the<br>
> +  // memory pointed to by globals at exit.  This is popular because it also<br>
> +  // solves another problem where the main thread of a C++ program may shut down<br>
> +  // before other threads that are still expecting to use those globals.  To<br>
> +  // handle that case, we expect the program may create a singleton and never<br>
> +  // destroy it.<br>
> +<br>
> +  bool Changed = false;<br>
> +<br>
> +  // If Dead[n].first is the only use of a malloc result, we can delete its<br>
> +  // chain of computation and the store to the global in Dead[n].second.<br>
> +  SmallVector<std::pair<Instruction *, Instruction *>, 32> Dead;<br>
> +<br>
> +  // Constants can't be pointers to dynamically allocated memory.<br>
> +  for (Value::use_iterator UI = GV->use_begin(), E = GV->use_end();<br>
> +       UI != E;) {<br>
> +    User *U = *UI++;<br>
> +    if (StoreInst *SI = dyn_cast<StoreInst>(U)) {<br>
> +      Value *V = SI->getValueOperand();<br>
> +      if (isa<Constant>(V)) {<br>
> +        Changed = true;<br>
> +        SI->eraseFromParent();<br>
> +      } else if (Instruction *I = dyn_cast<Instruction>(V)) {<br>
> +        if (I->hasOneUse())<br>
> +          Dead.push_back(std::make_pair(I, SI));<br>
> +      }<br>
> +    } else if (MemSetInst *MSI = dyn_cast<MemSetInst>(U)) {<br>
> +      if (isa<Constant>(MSI->getValue())) {<br>
> +        Changed = true;<br>
> +        MSI->eraseFromParent();<br>
> +      } else if (Instruction *I = dyn_cast<Instruction>(MSI->getValue())) {<br>
> +        if (I->hasOneUse())<br>
> +          Dead.push_back(std::make_pair(I, MSI));<br>
> +      }<br>
> +    } else if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(U)) {<br>
> +      GlobalVariable *MemSrc = dyn_cast<GlobalVariable>(MTI->getSource());<br>
> +      if (MemSrc && MemSrc->isConstant()) {<br>
> +        Changed = true;<br>
> +        MTI->eraseFromParent();<br>
> +      } else if (Instruction *I = dyn_cast<Instruction>(MemSrc)) {<br>
> +        if (I->hasOneUse())<br>
> +          Dead.push_back(std::make_pair(I, MTI));<br>
> +      }<br>
> +    } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {<br>
> +      if (CE->use_empty()) {<br>
> +        CE->destroyConstant();<br>
> +        Changed = true;<br>
> +      }<br>
> +    } else if (Constant *C = dyn_cast<Constant>(U)) {<br>
> +      if (SafeToDestroyConstant(C)) {<br>
> +        C->destroyConstant();<br>
> +        // This could have invalidated UI, start over from scratch.<br>
> +        Dead.clear();<br>
> +        CleanupPointerRootUsers(GV);<br>
> +        return true;<br>
> +      }<br>
> +    }<br>
> +  }<br>
> +<br>
> +  for (int i = 0, e = Dead.size(); i != e; ++i) {<br>
> +    if (IsSafeComputationToRemove(Dead[i].first)) {<br>
> +      Dead[i].second->eraseFromParent();<br>
> +      Instruction *I = Dead[i].first;<br>
> +      do {<br>
> +        Instruction *J = dyn_cast<Instruction>(I->getOperand(0));<br>
> +        if (!J)<br>
> +          break;<br>
> +        I->eraseFromParent();<br>
> +        I = J;<br>
> +      } while (!isAllocationFn(I));<br>
> +      I->eraseFromParent();<br>
> +    }<br>
> +  }<br>
> +<br>
> +  return Changed;<br>
> +}<br>
> +<br>
> /// CleanupConstantGlobalUsers - We just marked GV constant.  Loop over all<br>
> /// users of the global, cleaning up the obvious ones.  This is largely just a<br>
> /// quick scan over the use list to clean up the easy and obvious cruft.  This<br>
> @@ -812,13 +971,18 @@<br>
>   // If we nuked all of the loads, then none of the stores are needed either,<br>
>   // nor is the global.<br>
>   if (AllNonStoreUsesGone) {<br>
> -    DEBUG(dbgs() << "  *** GLOBAL NOW DEAD!\n");<br>
> -    CleanupConstantGlobalUsers(GV, 0, TD, TLI);<br>
> +    if (isLeakCheckerRoot(GV)) {<br>
> +      Changed |= CleanupPointerRootUsers(GV);<br>
> +    } else {<br>
> +      Changed = true;<br>
> +      CleanupConstantGlobalUsers(GV, 0, TD, TLI);<br>
> +    }<br>
>     if (GV->use_empty()) {<br>
> +      DEBUG(dbgs() << "  *** GLOBAL NOW DEAD!\n");<br>
> +      Changed = true;<br>
>       GV->eraseFromParent();<br>
>       ++NumDeleted;<br>
>     }<br>
> -    Changed = true;<br>
>   }<br>
>   return Changed;<br>
> }<br>
> @@ -1794,10 +1958,15 @@<br>
>   if (!GS.isLoaded) {<br>
>     DEBUG(dbgs() << "GLOBAL NEVER LOADED: " << *GV);<br>
><br>
> -    // Delete any stores we can find to the global.  We may not be able to<br>
> -    // make it completely dead though.<br>
> -    bool Changed = CleanupConstantGlobalUsers(GV, GV->getInitializer(),<br>
> -                                              TD, TLI);<br>
> +    bool Changed;<br>
> +    if (isLeakCheckerRoot(GV)) {<br>
> +      // Delete any constant stores to the global.<br>
> +      Changed = CleanupPointerRootUsers(GV);<br>
> +    } else {<br>
> +      // Delete any stores we can find to the global.  We may not be able to<br>
> +      // make it completely dead though.<br>
> +      Changed = CleanupConstantGlobalUsers(GV, GV->getInitializer(), TD, TLI);<br>
> +    }<br>
><br>
>     // If the global is dead now, delete it.<br>
>     if (GV->use_empty()) {<br>
> @@ -1845,7 +2014,7 @@<br>
><br>
>         if (GV->use_empty()) {<br>
>           DEBUG(dbgs() << "   *** Substituting initializer allowed us to "<br>
> -                << "simplify all users and delete global!\n");<br>
> +                       << "simplify all users and delete global!\n");<br>
>           GV->eraseFromParent();<br>
>           ++NumDeleted;<br>
>         } else {<br>
><br>
> Modified: llvm/trunk/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll?rev=160664&r1=160663&r2=160664&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll?rev=160664&r1=160663&r2=160664&view=diff</a><br>


> ==============================================================================<br>
> --- llvm/trunk/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll (original)<br>
> +++ llvm/trunk/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll Tue Jul 24 02:21:08 2012<br>
> @@ -17,7 +17,7 @@<br>
>   %2 = sext i32 %1 to i64                         ; <i64> [#uses=1]<br>
>   %3 = mul i64 %2, ptrtoint (%struct.strchartype* getelementptr (%struct.strchartype* null, i64 1) to i64) ; <i64> [#uses=1]<br>
>   %4 = tail call i8* @malloc(i64 %3)              ; <i8*> [#uses=1]<br>
> -; CHECK: call i8* @malloc(i64<br>
> +; CHECK-NOT: call i8* @malloc(i64<br>
>   %5 = bitcast i8* %4 to %struct.strchartype*     ; <%struct.strchartype*> [#uses=1]<br>
>   store %struct.strchartype* %5, %struct.strchartype** @chartypes, align 8<br>
>   ret void<br>
><br>
> Added: llvm/trunk/test/Transforms/GlobalOpt/cleanup-pointer-root-users.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/cleanup-pointer-root-users.ll?rev=160664&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/cleanup-pointer-root-users.ll?rev=160664&view=auto</a><br>


> ==============================================================================<br>
> --- llvm/trunk/test/Transforms/GlobalOpt/cleanup-pointer-root-users.ll (added)<br>
> +++ llvm/trunk/test/Transforms/GlobalOpt/cleanup-pointer-root-users.ll Tue Jul 24 02:21:08 2012<br>
> @@ -0,0 +1,19 @@<br>
> +; RUN: opt -globalopt -S -o - < %s | FileCheck %s<br>
> +<br>
> +@test1 = internal global i8* null<br>
> +<br>
> +define void @test1a() {<br>
> +; CHECK: @test1a<br>
> +; CHECK-NOT: store<br>
> +; CHECK-NEXT: ret void<br>
> +  store i8* null, i8** @test1<br>
> +  ret void<br>
> +}<br>
> +<br>
> +define void @test1b(i8* %p) {<br>
> +; CHECK: @test1b<br>
> +; CHECK-NEXT: store<br>
> +; CHECK-NEXT: ret void<br>
> +  store i8* %p, i8** @test1<br>
> +  ret void<br>
> +}<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br>
<br>
<br>
-David<br>
<br>
<br>
<br>_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br></blockquote></div><br>