[SimplifyCFG] FoldBranchToCommonDest: gracefully handle unreachable code ()

We might be dealing with an unreachable code,
so the bonus instruction we clone might be self-referencing.

There is a sanity check that all uses of bonus instructions
that are not in the original block with said bonus instructions
are PHI nodes, and that is obviously not the case
for self-referencing instructions..

So if we find such an use, just rewrite it.

Thanks to Mikael Holmén for the reproducer!

Fixes https://bugs.llvm.org/show_bug.cgi?id=48450#c8
This commit is contained in:
Roman Lebedev 2020-12-28 23:30:38 +03:00
parent f931290308
commit ef93f7a11c
No known key found for this signature in database
GPG Key ID: 083C3EBB4A1689E0
2 changed files with 61 additions and 0 deletions

View File

@ -2986,6 +2986,13 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU,
"Non-external users are never PHI instructions.");
return false;
}
if (User->getParent() == PredBlock) {
// The "exteral" use is in the block into which we just cloned the
// bonus instruction. This means two things: 1. we are in an
// unreachable block 2. the instruction is self-referencing.
// So let's just rewrite it...
return true;
}
(void)BI;
assert(isa<PHINode>(User) && "All external users must be PHI's.");
auto *PN = cast<PHINode>(User);

View File

@ -836,3 +836,57 @@ for.bodythread-pre-split.loopback:
if.end.loopexit:
ret void
}
@f.b = external global i16, align 1
define void @pr48450_3() {
; CHECK-LABEL: @pr48450_3(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_COND1:%.*]]
; CHECK: for.cond1:
; CHECK-NEXT: [[V:%.*]] = load i16, i16* @f.b, align 1
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[V]], 1
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: br label [[FOR_COND1]]
;
entry:
br label %for.cond1
for.cond1:
%v = load i16, i16* @f.b, align 1
%cmp = icmp slt i16 %v, 1
br i1 %cmp, label %for.body, label %for.end
for.body:
br label %for.cond1
for.end:
%tobool = icmp ne i16 %v, 0
br i1 %tobool, label %if.then, label %if.end
if.then:
unreachable
if.end:
br label %for.cond2
for.cond2:
%c.0 = phi i16 [ undef, %if.end ], [ %inc, %if.end7 ]
%cmp3 = icmp slt i16 %c.0, 1
br i1 %cmp3, label %for.body4, label %for.cond.cleanup
for.cond.cleanup:
br label %cleanup
for.body4:
br i1 undef, label %if.then6, label %if.end7
if.then6:
br label %cleanup
if.end7:
%inc = add nsw i16 %c.0, 1
br label %for.cond2
cleanup:
unreachable
}