PopSucc->removePredecessor(OrigBlock);
return;
}
+
+ // If the condition was a PHI node with the switch block as a predecessor
+ // removing predecessors may have caused the condition to be erased.
+ // Getting the condition value again here protects against that.
+ Val = SI->getCondition();
}
// Create a new, empty default block so that the new hierarchy of
--- /dev/null
+; RUN: opt < %s -lowerswitch -S | FileCheck %s
+
+; This test verifies -lowerswitch does not crash when an removing an
+; unreachable default branch causes a PHI node used as the switch
+; condition to be erased.
+
+define void @f() local_unnamed_addr {
+entry:
+ br label %sw.epilog
+
+sw.epilog: ; preds = %sw.epilog.outer, %for.body
+ %i = phi i32 [ undef, %for.body ], [ 0, %entry ]
+ br i1 undef, label %for.body, label %for.end
+
+for.body: ; preds = %sw.epilog
+ switch i32 %i, label %sw.epilog [
+ i32 0, label %sw.epilog.outer.backedge.loopexit
+ i32 1, label %sw.epilog.outer.backedge
+ ]
+
+sw.epilog.outer.backedge.loopexit: ; preds = %for.body
+ br label %for.end
+
+sw.epilog.outer.backedge: ; preds = %for.body
+ unreachable
+
+for.end: ; preds = %sw.epilog
+ ret void
+}
+
+; The phi and the switch should both be eliminated.
+; CHECK: @f()
+; CHECK: sw.epilog:
+; CHECK-NOT: phi
+; CHECK: for.body:
+; CHECK-NOT: switch