<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Nov 29, 2016 at 4:54 AM, Chandler Carruth via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: chandlerc<br>
Date: Tue Nov 29 06:54:34 2016<br>
New Revision: 288135<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=288135&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=288135&view=rev</a><br>
Log:<br>
[PM] Fix a bad invalid densemap iterator bug in the new invalidation<br>
logic.<br>
<br>
Yup, the invalidation logic has an invalid iterator bug. Can't make this<br>
stuff up.<br>
<br>
We can recursively insert things into the map so we can't cache the<br>
iterator into that map across those recursive calls. We did this<br>
differently in two places. I have an end-to-end test that triggers at<br>
least one of them. I'm going to work on a nice minimal test case that<br>
triggers these, but I didn't want to leave the bug in the tree while<br>
I tried to trigger it.<br>
<br>
Also, the dense map iterator checking stuff we have now is awesome. =D<br></blockquote><div><br></div><div>It saved me too when I was working on the new PM!</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Modified:<br>
    llvm/trunk/include/llvm/IR/<wbr>PassManager.h<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<wbr>PassManager.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=288135&r1=288134&r2=288135&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/include/<wbr>llvm/IR/PassManager.h?rev=<wbr>288135&r1=288134&r2=288135&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/IR/<wbr>PassManager.h (original)<br>
+++ llvm/trunk/include/llvm/IR/<wbr>PassManager.h Tue Nov 29 06:54:34 2016<br>
@@ -399,13 +399,11 @@ public:<br>
     template <typename PassT><br>
     bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA) {<br>
       AnalysisKey *ID = PassT::ID();<br>
-      SmallDenseMap<AnalysisKey *, bool, 8>::iterator IMapI;<br>
-      bool Inserted;<br>
-      std::tie(IMapI, Inserted) = IsResultInvalidated.insert({<wbr>ID, false});<br>
<br>
       // If we've already visited this pass, return true if it was invalidated<br>
       // and false otherwise.<br>
-      if (!Inserted)<br>
+      auto IMapI = IsResultInvalidated.find(ID);<br>
+      if (IMapI != IsResultInvalidated.end())<br>
         return IMapI->second;<br>
<br>
       // Otherwise look up the result object.<br>
@@ -421,9 +419,16 @@ public:<br>
           ResultModelT;<br>
       auto &ResultModel = static_cast<ResultModelT &>(*RI->second->second);<br>
<br>
-      // Mark in the map whether the result should be invalidated and return<br>
-      // that.<br>
-      IMapI->second = ResultModel.invalidate(IR, PA, *this);<br>
+      // Insert into the map whether the result should be invalidated and<br>
+      // return that. Note that we cannot re-use IMapI and must do a fresh<br>
+      // insert here as calling the invalidate routine could (recursively)<br>
+      // insert things into the map making any iterator or reference invalid.<br>
+      bool Inserted;<br>
+      std::tie(IMapI, Inserted) = IsResultInvalidated.insert(<br>
+          {ID, ResultModel.invalidate(IR, PA, *this)});<br>
+      (void)Inserted;<br>
+      assert(Inserted && "Should not have already inserted this ID, likely "<br>
+                         "indicates a dependency cycle!");<br>
       return IMapI->second;<br>
     }<br>
<br>
@@ -593,16 +598,22 @@ public:<br>
       AnalysisKey *ID = AnalysisResultPair.first;<br>
       auto &Result = *AnalysisResultPair.second;<br>
<br>
-      SmallDenseMap<AnalysisKey *, bool, 8>::iterator IMapI;<br>
-      bool Inserted;<br>
-      std::tie(IMapI, Inserted) = IsResultInvalidated.insert({<wbr>ID, false});<br>
-      if (!Inserted)<br>
+      auto IMapI = IsResultInvalidated.find(ID);<br>
+      if (IMapI != IsResultInvalidated.end())<br>
         // This result was already handled via the Invalidator.<br>
         continue;<br>
<br>
       // Try to invalidate the result, giving it the Invalidator so it can<br>
       // recursively query for any dependencies it has and record the result.<br>
-      IMapI->second = Result.invalidate(IR, PA, Inv);<br>
+      // Note that we cannot re-use 'IMapI' here or pre-insert the ID as the<br>
+      // invalidate method may insert things into the map as well, invalidating<br>
+      // any iterator or pointer.<br>
+      bool Inserted =<br>
+          IsResultInvalidated.insert({<wbr>ID, Result.invalidate(IR, PA, Inv)})<br>
+              .second;<br>
+      (void)Inserted;<br>
+      assert(Inserted && "Should never have already inserted this ID, likely "<br>
+                         "indicates a cycle!");<br>
     }<br>
<br>
     // Now erase the results that were marked above as invalidated.<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>