Indvars: Don't recursively delete instruction during BB iteration.
authorBenjamin Kramer <benny.kra@googlemail.com>
Fri, 19 Oct 2012 17:53:54 +0000 (17:53 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Fri, 19 Oct 2012 17:53:54 +0000 (17:53 +0000)
This can invalidate the iterators leading to use after frees and crashes.
Fixes PR12536.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166291 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/IndVarSimplify.cpp
test/Transforms/IndVarSimplify/crash.ll

index 78630b2a9f38cc2c02dcf447445d7fabfd40f066..82eb7464677262eecd6a736047afb69251cf03d9 100644 (file)
@@ -551,15 +551,17 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter) {
 
         PN->setIncomingValue(i, ExitVal);
 
-        // If this instruction is dead now, delete it.
-        RecursivelyDeleteTriviallyDeadInstructions(Inst, TLI);
+        // If this instruction is dead now, delete it. Don't do it now to avoid
+        // invalidating iterators.
+        if (isInstructionTriviallyDead(Inst, TLI))
+          DeadInsts.push_back(Inst);
 
         if (NumPreds == 1) {
           // Completely replace a single-pred PHI. This is safe, because the
           // NewVal won't be variant in the loop, so we don't need an LCSSA phi
           // node anymore.
           PN->replaceAllUsesWith(ExitVal);
-          RecursivelyDeleteTriviallyDeadInstructions(PN, TLI);
+          PN->eraseFromParent();
         }
       }
       if (NumPreds != 1) {
index 62af42b9d68d27b53d46a0942e91ab485c4fc87a..1b702a3b1a3c9cff688058a55eef7f3afa972fa7 100644 (file)
@@ -113,3 +113,21 @@ bb9:
   ret void
 }
 
+; PR12536
+define void @fn1() noreturn nounwind {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.end, %entry
+  %b.0 = phi i32 [ undef, %entry ], [ %conv, %for.end ]
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.cond1, %for.cond
+  %c.0 = phi i32 [ %b.0, %for.cond1 ], [ 0, %for.cond ]
+  br i1 undef, label %for.cond1, label %for.end
+
+for.end:                                          ; preds = %for.cond1
+  %cmp2 = icmp slt i32 %c.0, 1
+  %conv = zext i1 %cmp2 to i32
+  br label %for.cond
+}