Peculiarly, the non-permissive variant handled this gracefully,
but the permissive one did not.
std::function<void(Value *)> AboutToDeleteCallback) {
unsigned S = 0, E = DeadInsts.size(), Alive = 0;
for (; S != E; ++S) {
- auto *I = dyn_cast<Instruction>(DeadInsts[S]);
+ auto *I = dyn_cast_or_null<Instruction>(DeadInsts[S]);
if (!I || !isInstructionTriviallyDead(I)) {
DeadInsts[S] = nullptr;
++Alive;
ret void
}
+define internal ptr @callee(ptr %dead) {
+; CHECK-LABEL: define internal ptr @callee() {
+; CHECK-NEXT: ret ptr null
+;
+ ret ptr null
+}
+
+define void @caller() {
+; CHECK-LABEL: define void @caller() {
+; CHECK-NEXT: [[TMP1:%.*]] = call ptr @callee()
+; CHECK-NEXT: [[TMP2:%.*]] = call ptr @callee()
+; CHECK-NEXT: ret void
+;
+ %ret = call ptr @callee(ptr null)
+ %ret2 = call ptr @callee(ptr %ret)
+ ret void
+}