llvm.org GIT mirror llvm / 5c5b3cf
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! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165065 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 7 years ago
3 changed file(s) with 59 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
125125 return false;
126126 }
127127
128 /// \brief Remove items from the set vector based on a predicate function.
129 ///
130 /// This is intended to be equivalent to the following code, if we could
131 /// write it:
132 ///
133 /// \code
134 /// V.erase(std::remove_if(V.begin(), V.end(), P), V.end());
135 /// \endcode
136 ///
137 /// However, SetVector doesn't expose non-const iterators, making any
138 /// algorithm like remove_if impossible to use.
139 ///
140 /// \returns true if any element is removed.
141 template
142 bool remove_if(UnaryPredicate P) {
143 typename vector_type::iterator B = std::remove_if(vector_.begin(),
144 vector_.end(), P),
145 E = vector_.end();
146 if (B == E)
147 return false;
148 for (typename vector_type::iterator I = B; I != E; ++I)
149 set_.erase(*I);
150 vector_.erase(B, E);
151 return true;
152 }
153
128154
129155 /// \brief Count the number of elements of a given key in the SetVector.
130156 /// \returns 0 if the element is not in the SetVector, 1 if it is.
33013301 while (!Worklist.empty()) {
33023302 Changed |= runOnAlloca(*Worklist.pop_back_val());
33033303 deleteDeadInstructions(DeletedAllocas);
3304
3305 // Remove the deleted allocas from various lists so that we don't try to
3306 // continue processing them.
33043307 if (!DeletedAllocas.empty()) {
3308 Worklist.remove_if(IsAllocaInSet(DeletedAllocas));
33053309 PromotableAllocas.erase(std::remove_if(PromotableAllocas.begin(),
33063310 PromotableAllocas.end(),
33073311 IsAllocaInSet(DeletedAllocas)),
896896 %tmp2 = load i8* %gep
897897 ret void
898898 }
899
900 define void @PR13990() {
901 ; Ensure we can handle cases where processing one alloca causes the other
902 ; alloca to become dead and get deleted. This might crash or fail under
903 ; Valgrind if we regress.
904 ; CHECK: @PR13990
905 ; CHECK-NOT: alloca
906 ; CHECK: unreachable
907 ; CHECK: unreachable
908
909 entry:
910 %tmp1 = alloca i8*
911 %tmp2 = alloca i8*
912 br i1 undef, label %bb1, label %bb2
913
914 bb1:
915 store i8* undef, i8** %tmp2
916 br i1 undef, label %bb2, label %bb3
917
918 bb2:
919 %tmp50 = select i1 undef, i8** %tmp2, i8** %tmp1
920 br i1 undef, label %bb3, label %bb4
921
922 bb3:
923 unreachable
924
925 bb4:
926 unreachable
927 }