[SimplifyCFG] simplifyUnreachable(): fix handling of degenerate same-destination conditional branch

One would hope that it would have been already canonicalized into an
unconditional branch, but that isn't really guaranteed to happen
with SimplifyCFG's visitation order.
This commit is contained in:
Roman Lebedev 2021-01-05 14:49:54 +03:00
parent 3460719f58
commit 29ca7d5a1a
No known key found for this signature in database
GPG Key ID: 083C3EBB4A1689E0
2 changed files with 8 additions and 14 deletions

View File

@ -4683,16 +4683,18 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) {
Instruction *TI = Predecessor->getTerminator();
IRBuilder<> Builder(TI);
if (auto *BI = dyn_cast<BranchInst>(TI)) {
if (BI->isUnconditional()) {
assert(BI->getSuccessor(0) == BB && "Incorrect CFG");
// We could either have a proper unconditional branch,
// or a degenerate conditional branch with matching destinations.
if (all_of(BI->successors(),
[BB](auto *Successor) { return Successor == BB; })) {
new UnreachableInst(TI->getContext(), TI);
TI->eraseFromParent();
Changed = true;
} else {
assert(BI->isConditional() && "Can't get here with an uncond branch.");
Value* Cond = BI->getCondition();
// assert(BI->getSuccessor(0) != BI->getSuccessor(1) &&
// "Same-destination conditional branch instruction was "
// "already canonicalized into an unconditional branch.");
assert(BI->getSuccessor(0) != BI->getSuccessor(1) &&
"The destinations are guaranteed to be different here.");
if (BI->getSuccessor(0) == BB) {
Builder.CreateAssumption(Builder.CreateNot(Cond));
Builder.CreateBr(BI->getSuccessor(1));

View File

@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -simplifycfg -simplifycfg-require-and-preserve-domtree=0 < %s | FileCheck %s
; RUN: opt -S -simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s
@global = external global i16, align 1
@global.1 = external global i16, align 1
@ -11,14 +11,6 @@ define void @widget() {
; CHECK-NEXT: [[I:%.*]] = load i16, i16* @global, align 1
; CHECK-NEXT: [[I13:%.*]] = icmp ne i16 [[I]], 0
; CHECK-NEXT: call void @llvm.assume(i1 [[I13]])
; CHECK-NEXT: [[I17:%.*]] = load i16, i16* @global, align 1
; CHECK-NEXT: [[I18:%.*]] = sdiv i16 2, [[I17]]
; CHECK-NEXT: [[I19:%.*]] = icmp ne i16 [[I18]], 0
; CHECK-NEXT: [[I20:%.*]] = zext i1 [[I19]] to i16
; CHECK-NEXT: [[I21:%.*]] = load i16, i16* @global.1, align 1
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[I19]], i16 [[I20]], i16 [[I21]]
; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[I19]], true
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
; CHECK-NEXT: unreachable
;
bb: