Skip to content

Commit fcab72c

Browse files
committed
Bail out jump threading on indirect branches
The bug was introduced by #68473
1 parent 2a6136e commit fcab72c

File tree

2 files changed

+81
-2
lines changed

2 files changed

+81
-2
lines changed

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,12 @@ CanPropagatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ,
868868

869869
LLVM_DEBUG(dbgs() << "Looking to fold " << BB->getName() << " into "
870870
<< Succ->getName() << "\n");
871+
if (isa<IndirectBrInst>(Succ->getTerminator()) ||
872+
any_of(BBPreds, [](const BasicBlock *Pred) {
873+
return isa<IndirectBrInst>(Pred->getTerminator());
874+
}))
875+
return false;
876+
871877
// Shortcut, if there is only a single predecessor it must be BB and merging
872878
// is always safe
873879
if (Succ->getSinglePredecessor())
@@ -1028,7 +1034,13 @@ CanRedirectPredsOfEmptyBBToSucc(BasicBlock *BB, BasicBlock *Succ,
10281034
if (!BB->hasNPredecessorsOrMore(2))
10291035
return false;
10301036

1031-
// Get single common predecessors of both BB and Succ
1037+
if (any_of(BBPreds, [](const BasicBlock *Pred) {
1038+
return isa<IndirectBrInst>(Pred->getTerminator());
1039+
}))
1040+
return false;
1041+
1042+
// Get the single common predecessor of both BB and Succ. Return false
1043+
// when there are more than one common predecessors.
10321044
for (BasicBlock *SuccPred : SuccPreds) {
10331045
if (BBPreds.count(SuccPred)) {
10341046
if (CommonPred)
@@ -1133,7 +1145,7 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
11331145

11341146
bool BBKillable = CanPropagatePredecessorsForPHIs(BB, Succ, BBPreds);
11351147

1136-
// Even if we can not fold bB into Succ, we may be able to redirect the
1148+
// Even if we can not fold BB into Succ, we may be able to redirect the
11371149
// predecessors of BB to Succ.
11381150
bool BBPhisMergeable =
11391151
BBKillable ||
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
; RUN: opt < %s -passes=simplifycfg -S | FileCheck %s
2+
3+
; CHECK: switch i32 %state.0, label %sw.epilog
4+
; CHECK-NEXT: i32 0, label %sw.bb
5+
; CHECK-NEXT: i32 1, label %VM__OP_1
6+
; CHECK-NEXT: i32 2, label %sw.bb4
7+
8+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
9+
target triple = "x86_64-unknown-linux-gnu"
10+
11+
@global = private unnamed_addr constant [23 x i8] c"OP_1:(instruction=%d)\0A\00", align 1
12+
@global.1 = private unnamed_addr constant [28 x i8] c"TERMINATE:(instruction=%d)\0A\00", align 1
13+
14+
define dso_local noundef i32 @main() {
15+
bb:
16+
%alloca = alloca [2 x ptr], align 16
17+
store ptr blockaddress(@main, %bb4), ptr %alloca, align 16, !tbaa !0
18+
%getelementptr = getelementptr inbounds [2 x ptr], ptr %alloca, i64 0, i64 1
19+
store ptr blockaddress(@main, %bb10), ptr %getelementptr, align 8, !tbaa !0
20+
br label %bb1
21+
22+
bb1: ; preds = %bb7, %bb
23+
%phi = phi i32 [ 0, %bb ], [ %phi8, %bb7 ]
24+
%phi2 = phi i32 [ 0, %bb ], [ %phi9, %bb7 ]
25+
switch i32 %phi, label %bb7 [
26+
i32 0, label %bb3
27+
i32 1, label %bb4
28+
i32 2, label %bb6
29+
]
30+
31+
bb3: ; preds = %bb1
32+
br label %bb12
33+
34+
bb4: ; preds = %bb12, %bb1
35+
%phi5 = phi i32 [ %phi13, %bb12 ], [ %phi2, %bb1 ]
36+
br label %bb7
37+
38+
bb6: ; preds = %bb1
39+
%call = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @global, i32 noundef %phi2)
40+
%add = add nsw i32 %phi2, 1
41+
br label %bb12
42+
43+
bb7: ; preds = %bb4, %bb1
44+
%phi8 = phi i32 [ %phi, %bb1 ], [ 2, %bb4 ]
45+
%phi9 = phi i32 [ %phi2, %bb1 ], [ %phi5, %bb4 ]
46+
br label %bb1, !llvm.loop !4
47+
48+
bb10: ; preds = %bb12
49+
%call11 = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @global.1, i32 noundef %phi13)
50+
ret i32 0
51+
52+
bb12: ; preds = %bb6, %bb3
53+
%phi13 = phi i32 [ %add, %bb6 ], [ %phi2, %bb3 ]
54+
%sext = sext i32 %phi13 to i64
55+
%getelementptr14 = getelementptr inbounds [2 x ptr], ptr %alloca, i64 0, i64 %sext
56+
%load = load ptr, ptr %getelementptr14, align 8, !tbaa !0
57+
indirectbr ptr %load, [label %bb4, label %bb10]
58+
}
59+
60+
declare i32 @printf(ptr noundef, ...)
61+
62+
!0 = !{!1, !1, i64 0}
63+
!1 = !{!"any pointer", !2, i64 0}
64+
!2 = !{!"omnipotent char", !3, i64 0}
65+
!3 = !{!"Simple C++ TBAA"}
66+
!4 = !{!5, !5, i64 0}
67+
!5 = !{!"int", !2, i64 0}

0 commit comments

Comments
 (0)