[llvm-commits] [llvm] r165065 - in /llvm/trunk: include/llvm/ADT/SetVector.h lib/Transforms/Scalar/SROA.cpp test/Transforms/SROA/basictest.ll

Chandler Carruth chandlerc at gmail.com
Tue Oct 2 15:46:45 PDT 2012


Author: chandlerc
Date: Tue Oct  2 17:46:45 2012
New Revision: 165065

URL: http://llvm.org/viewvc/llvm-project?rev=165065&view=rev
Log:
Teach the new SROA to handle cases where an alloca that has already been
scheduled for processing on the worklist eventually gets deleted while
we are processing another alloca, fixing the original test case in
PR13990.

To facilitate this, add a remove_if helper to the SetVector abstraction.
It's not easy to use the standard abstractions for this because of the
specifics of SetVectors types and implementation.

Finally, a nice small test case is included. Thanks to Benjamin for the
fantastic reduced test case here! All I had to do was delete some empty
basic blocks!

Modified:
    llvm/trunk/include/llvm/ADT/SetVector.h
    llvm/trunk/lib/Transforms/Scalar/SROA.cpp
    llvm/trunk/test/Transforms/SROA/basictest.ll

Modified: llvm/trunk/include/llvm/ADT/SetVector.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SetVector.h?rev=165065&r1=165064&r2=165065&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/SetVector.h (original)
+++ llvm/trunk/include/llvm/ADT/SetVector.h Tue Oct  2 17:46:45 2012
@@ -126,6 +126,32 @@
     return false;
   }
 
+  /// \brief Remove items from the set vector based on a predicate function.
+  ///
+  /// This is intended to be equivalent to the following code, if we could
+  /// write it:
+  ///
+  /// \code
+  ///   V.erase(std::remove_if(V.begin(), V.end(), P), V.end());
+  /// \endcode
+  ///
+  /// However, SetVector doesn't expose non-const iterators, making any
+  /// algorithm like remove_if impossible to use.
+  ///
+  /// \returns true if any element is removed.
+  template <typename UnaryPredicate>
+  bool remove_if(UnaryPredicate P) {
+    typename vector_type::iterator B = std::remove_if(vector_.begin(),
+                                                      vector_.end(), P),
+                                   E = vector_.end();
+    if (B == E)
+      return false;
+    for (typename vector_type::iterator I = B; I != E; ++I)
+      set_.erase(*I);
+    vector_.erase(B, E);
+    return true;
+  }
+
 
   /// \brief Count the number of elements of a given key in the SetVector.
   /// \returns 0 if the element is not in the SetVector, 1 if it is.

Modified: llvm/trunk/lib/Transforms/Scalar/SROA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SROA.cpp?rev=165065&r1=165064&r2=165065&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SROA.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SROA.cpp Tue Oct  2 17:46:45 2012
@@ -3302,7 +3302,11 @@
   while (!Worklist.empty()) {
     Changed |= runOnAlloca(*Worklist.pop_back_val());
     deleteDeadInstructions(DeletedAllocas);
+
+    // Remove the deleted allocas from various lists so that we don't try to
+    // continue processing them.
     if (!DeletedAllocas.empty()) {
+      Worklist.remove_if(IsAllocaInSet(DeletedAllocas));
       PromotableAllocas.erase(std::remove_if(PromotableAllocas.begin(),
                                              PromotableAllocas.end(),
                                              IsAllocaInSet(DeletedAllocas)),

Modified: llvm/trunk/test/Transforms/SROA/basictest.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SROA/basictest.ll?rev=165065&r1=165064&r2=165065&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SROA/basictest.ll (original)
+++ llvm/trunk/test/Transforms/SROA/basictest.ll Tue Oct  2 17:46:45 2012
@@ -897,3 +897,32 @@
   %tmp2 = load i8* %gep
   ret void
 }
+
+define void @PR13990() {
+; Ensure we can handle cases where processing one alloca causes the other
+; alloca to become dead and get deleted. This might crash or fail under
+; Valgrind if we regress.
+; CHECK: @PR13990
+; CHECK-NOT: alloca
+; CHECK: unreachable
+; CHECK: unreachable
+
+entry:
+  %tmp1 = alloca i8*
+  %tmp2 = alloca i8*
+  br i1 undef, label %bb1, label %bb2
+
+bb1:
+  store i8* undef, i8** %tmp2
+  br i1 undef, label %bb2, label %bb3
+
+bb2:
+  %tmp50 = select i1 undef, i8** %tmp2, i8** %tmp1
+  br i1 undef, label %bb3, label %bb4
+
+bb3:
+  unreachable
+
+bb4:
+  unreachable
+}





More information about the llvm-commits mailing list