diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index 7ee40273347..fc3b38ee53b 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/lib/Transforms/Scalar/Reassociate.cpp @@ -143,13 +143,9 @@ namespace { // So, if Rank(X) < Rank(Y) < Rank(Z), it means X is defined earlier // than Y which is defined earlier than Z. Permute "x | 1", "Y & 2", // "z" in the order of X-Y-Z is better than any other orders. - class PtrSortFunctor { - ArrayRef A; - - public: - PtrSortFunctor(ArrayRef Array) : A(Array) {} - bool operator()(unsigned LHSIndex, unsigned RHSIndex) { - return A[LHSIndex].getSymbolicRank() < A[RHSIndex].getSymbolicRank(); + struct PtrSortFunctor { + bool operator()(XorOpnd * const &LHS, XorOpnd * const &RHS) { + return LHS->getSymbolicRank() < RHS->getSymbolicRank(); } }; private: @@ -1274,7 +1270,7 @@ Value *Reassociate::OptimizeXor(Instruction *I, return 0; SmallVector Opnds; - SmallVector OpndIndices; + SmallVector OpndPtrs; Type *Ty = Ops[0].Op->getType(); APInt ConstOpnd(Ty->getIntegerBitWidth(), 0); @@ -1285,23 +1281,29 @@ Value *Reassociate::OptimizeXor(Instruction *I, XorOpnd O(V); O.setSymbolicRank(getRank(O.getSymbolicPart())); Opnds.push_back(O); - OpndIndices.push_back(Opnds.size() - 1); } else ConstOpnd ^= cast(V)->getValue(); } + // NOTE: From this point on, do *NOT* add/delete element to/from "Opnds". + // It would otherwise invalidate the "Opnds"'s iterator, and hence invalidate + // the "OpndPtrs" as well. For the similar reason, do not fuse this loop + // with the previous loop --- the iterator of the "Opnds" may be invalidated + // when new elements are added to the vector. + for (unsigned i = 0, e = Opnds.size(); i != e; ++i) + OpndPtrs.push_back(&Opnds[i]); + // Step 2: Sort the Xor-Operands in a way such that the operands containing // the same symbolic value cluster together. For instance, the input operand // sequence ("x | 123", "y & 456", "x & 789") will be sorted into: // ("x | 123", "x & 789", "y & 456"). - std::sort(OpndIndices.begin(), OpndIndices.end(), - XorOpnd::PtrSortFunctor(Opnds)); + std::sort(OpndPtrs.begin(), OpndPtrs.end(), XorOpnd::PtrSortFunctor()); // Step 3: Combine adjacent operands XorOpnd *PrevOpnd = 0; bool Changed = false; for (unsigned i = 0, e = Opnds.size(); i < e; i++) { - XorOpnd *CurrOpnd = &Opnds[OpndIndices[i]]; + XorOpnd *CurrOpnd = OpndPtrs[i]; // The combined value Value *CV;