This fixes the assertion failure reported in https://reviews.llvm.org/
D114889#
3166417,
by making RecursivelyDeleteTriviallyDeadInstructionsPermissive()
more permissive. As the function accepts a WeakTrackingVH, even if
originally only Instructions were inserted, we may end up with
different Value types after a RAUW operation. As such, we should
not assume that the vector only contains instructions.
Notably this matches the behavior of the
RecursivelyDeleteTriviallyDeadInstructions() function variant which
accepts a single value rather than vector.
std::function<void(Value *)> AboutToDeleteCallback) {
unsigned S = 0, E = DeadInsts.size(), Alive = 0;
for (; S != E; ++S) {
- auto *I = cast<Instruction>(DeadInsts[S]);
- if (!isInstructionTriviallyDead(I)) {
+ auto *I = dyn_cast<Instruction>(DeadInsts[S]);
+ if (!I || !isInstructionTriviallyDead(I)) {
DeadInsts[S] = nullptr;
++Alive;
}
--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -globalopt < %s | FileCheck %s
+
+; In this case an instruction queued for recursive deletion gets RAUWd with
+; a constant in the meantime. Make sure this does not cause an assertion
+; failure.
+
+@a = internal global i32** null
+@b = internal global i32*** @a
+
+define void @test() {
+; CHECK-LABEL: @test(
+; CHECK-NEXT: ret void
+;
+ %v1 = load i32***, i32**** @b
+ %v2 = load i32**, i32*** %v1
+ store i32** %v2, i32*** @a
+ ret void
+}
+