Skip to content

Commit ef93f7a

Browse files
committed
[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
1 parent f931290 commit ef93f7a

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2986,6 +2986,13 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU,
29862986
"Non-external users are never PHI instructions.");
29872987
return false;
29882988
}
2989+
if (User->getParent() == PredBlock) {
2990+
// The "exteral" use is in the block into which we just cloned the
2991+
// bonus instruction. This means two things: 1. we are in an
2992+
// unreachable block 2. the instruction is self-referencing.
2993+
// So let's just rewrite it...
2994+
return true;
2995+
}
29892996
(void)BI;
29902997
assert(isa<PHINode>(User) && "All external users must be PHI's.");
29912998
auto *PN = cast<PHINode>(User);

llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest.ll

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,3 +836,57 @@ for.bodythread-pre-split.loopback:
836836
if.end.loopexit:
837837
ret void
838838
}
839+
840+
@f.b = external global i16, align 1
841+
define void @pr48450_3() {
842+
; CHECK-LABEL: @pr48450_3(
843+
; CHECK-NEXT: entry:
844+
; CHECK-NEXT: br label [[FOR_COND1:%.*]]
845+
; CHECK: for.cond1:
846+
; CHECK-NEXT: [[V:%.*]] = load i16, i16* @f.b, align 1
847+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[V]], 1
848+
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
849+
; CHECK-NEXT: br label [[FOR_COND1]]
850+
;
851+
entry:
852+
br label %for.cond1
853+
854+
for.cond1:
855+
%v = load i16, i16* @f.b, align 1
856+
%cmp = icmp slt i16 %v, 1
857+
br i1 %cmp, label %for.body, label %for.end
858+
859+
for.body:
860+
br label %for.cond1
861+
862+
for.end:
863+
%tobool = icmp ne i16 %v, 0
864+
br i1 %tobool, label %if.then, label %if.end
865+
866+
if.then:
867+
unreachable
868+
869+
if.end:
870+
br label %for.cond2
871+
872+
for.cond2:
873+
%c.0 = phi i16 [ undef, %if.end ], [ %inc, %if.end7 ]
874+
%cmp3 = icmp slt i16 %c.0, 1
875+
br i1 %cmp3, label %for.body4, label %for.cond.cleanup
876+
877+
for.cond.cleanup:
878+
br label %cleanup
879+
880+
for.body4:
881+
br i1 undef, label %if.then6, label %if.end7
882+
883+
if.then6:
884+
br label %cleanup
885+
886+
if.end7:
887+
%inc = add nsw i16 %c.0, 1
888+
br label %for.cond2
889+
890+
cleanup:
891+
unreachable
892+
}

0 commit comments

Comments
 (0)