Skip to content

Commit cf75e83

Browse files
committed
[InstCombine] replace zombie unreachable values with 'undef' before erasing
The test (currently crashing) is reduced from the example provided in the post-commit discussion in D87149. Differential Revision: https://reviews.llvm.org/D87965
1 parent 2ae1822 commit cf75e83

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2813,6 +2813,9 @@ Instruction *InstCombinerImpl::visitUnreachableInst(UnreachableInst &I) {
28132813
if (SI->isVolatile())
28142814
return nullptr;
28152815

2816+
// A value may still have uses before we process it here (for example, in
2817+
// another unreachable block), so convert those to undef.
2818+
replaceInstUsesWith(*Prev, UndefValue::get(Prev->getType()));
28162819
eraseInstFromFunction(*Prev);
28172820
return &I;
28182821
}

llvm/test/Transforms/InstCombine/phi.ll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,3 +1181,39 @@ if.end: ; preds = %entry, %if.then
11811181
%cmp1 = icmp ne i32 %a.0, 0
11821182
ret i1 %cmp1
11831183
}
1184+
1185+
; This would crash trying to delete an instruction (conv)
1186+
; that still had uses because the user (the phi) was not
1187+
; updated to remove a use from an unreachable block (g.exit).
1188+
1189+
define void @main(i1 %cond, i16 %x) {
1190+
; CHECK-LABEL: @main(
1191+
; CHECK-NEXT: entry:
1192+
; CHECK-NEXT: br label [[FOR_COND:%.*]]
1193+
; CHECK: for.cond:
1194+
; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR_END:%.*]], label [[FOR_BODY:%.*]]
1195+
; CHECK: for.body:
1196+
; CHECK-NEXT: unreachable
1197+
; CHECK: g.exit:
1198+
; CHECK-NEXT: br label [[FOR_COND]]
1199+
; CHECK: for.end:
1200+
; CHECK-NEXT: ret void
1201+
;
1202+
entry:
1203+
br label %for.cond
1204+
1205+
for.cond:
1206+
%p = phi double [ %conv, %g.exit ], [ undef, %entry ]
1207+
br i1 %cond, label %for.end, label %for.body
1208+
1209+
for.body:
1210+
%conv = sitofp i16 %x to double
1211+
unreachable
1212+
1213+
g.exit:
1214+
br label %for.cond
1215+
1216+
for.end:
1217+
store double %p, double* undef
1218+
ret void
1219+
}

0 commit comments

Comments
 (0)