Skip to content

Commit 4ab37c0

Browse files
author
Chad Rosier
committedMay 6, 2016
[SimplifyCFG] Prefer a simplification based on a dominating condition.
Rather than merge two branches with a common destination. Differential Revision: http://reviews.llvm.org/D19743 llvm-svn: 268735
1 parent c7e4239 commit 4ab37c0

File tree

2 files changed

+72
-20
lines changed

2 files changed

+72
-20
lines changed
 

‎llvm/lib/Transforms/Utils/SimplifyCFG.cpp

+24-20
Original file line numberDiff line numberDiff line change
@@ -2706,26 +2706,6 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
27062706
if (CE->canTrap())
27072707
return false;
27082708

2709-
// If BI is reached from the true path of PBI and PBI's condition implies
2710-
// BI's condition, we know the direction of the BI branch.
2711-
if ((PBI->getSuccessor(0) == BI->getParent() ||
2712-
PBI->getSuccessor(1) == BI->getParent()) &&
2713-
PBI->getSuccessor(0) != PBI->getSuccessor(1) &&
2714-
BB->getSinglePredecessor()) {
2715-
bool FalseDest = PBI->getSuccessor(1) == BI->getParent();
2716-
Optional<bool> Implication = isImpliedCondition(
2717-
PBI->getCondition(), BI->getCondition(), DL, FalseDest);
2718-
if (Implication) {
2719-
// Turn this into a branch on constant.
2720-
auto *OldCond = BI->getCondition();
2721-
ConstantInt *CI = *Implication ? ConstantInt::getTrue(BB->getContext())
2722-
: ConstantInt::getFalse(BB->getContext());
2723-
BI->setCondition(CI);
2724-
RecursivelyDeleteTriviallyDeadInstructions(OldCond);
2725-
return true; // Nuke the branch on constant.
2726-
}
2727-
}
2728-
27292709
// If both branches are conditional and both contain stores to the same
27302710
// address, remove the stores from the conditionals and create a conditional
27312711
// merged store at the end.
@@ -5149,6 +5129,30 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
51495129
if (SimplifyBranchOnICmpChain(BI, Builder, DL))
51505130
return true;
51515131

5132+
// If this basic block has a single dominating predecessor block and the
5133+
// dominating block's condition implies BI's condition, we know the direction
5134+
// of the BI branch.
5135+
if (BasicBlock *Dom = BB->getSinglePredecessor()) {
5136+
auto *PBI = dyn_cast_or_null<BranchInst>(Dom->getTerminator());
5137+
if (PBI && PBI->isConditional() &&
5138+
PBI->getSuccessor(0) != PBI->getSuccessor(1) &&
5139+
(PBI->getSuccessor(0) == BB || PBI->getSuccessor(1) == BB)) {
5140+
bool CondIsFalse = PBI->getSuccessor(1) == BB;
5141+
Optional<bool> Implication = isImpliedCondition(
5142+
PBI->getCondition(), BI->getCondition(), DL, CondIsFalse);
5143+
if (Implication) {
5144+
// Turn this into a branch on constant.
5145+
auto *OldCond = BI->getCondition();
5146+
ConstantInt *CI = *Implication
5147+
? ConstantInt::getTrue(BB->getContext())
5148+
: ConstantInt::getFalse(BB->getContext());
5149+
BI->setCondition(CI);
5150+
RecursivelyDeleteTriviallyDeadInstructions(OldCond);
5151+
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
5152+
}
5153+
}
5154+
}
5155+
51525156
// If this basic block is ONLY a compare and a branch, and if a predecessor
51535157
// branches to us and one of our successors, fold the comparison into the
51545158
// predecessor and use logical operations to pick the right destination.

‎llvm/test/Transforms/SimplifyCFG/basictest.ll

+48
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,54 @@ define void @test3(i1 %T) {
2525
; CHECK-NEXT: ret void
2626
}
2727

28+
; Folding branch to a common destination.
29+
; CHECK-LABEL: @test4_fold
30+
; CHECK: %cmp1 = icmp eq i32 %a, %b
31+
; CHECK: %cmp2 = icmp ugt i32 %a, 0
32+
; CHECK: %or.cond = and i1 %cmp1, %cmp2
33+
; CHECK: br i1 %or.cond, label %else, label %untaken
34+
; CHECK-NOT: taken:
35+
; CHECK: ret void
36+
define void @test4_fold(i32 %a, i32 %b) {
37+
%cmp1 = icmp eq i32 %a, %b
38+
br i1 %cmp1, label %taken, label %untaken
39+
40+
taken:
41+
%cmp2 = icmp ugt i32 %a, 0
42+
br i1 %cmp2, label %else, label %untaken
43+
44+
else:
45+
call void @foo()
46+
ret void
47+
48+
untaken:
49+
ret void
50+
}
51+
52+
; Prefer a simplification based on a dominating condition rather than folding a
53+
; branch to a common destination.
54+
; CHECK-LABEL: @test4
55+
; CHECK-NOT: br
56+
; CHECK-NOT: br
57+
; CHECK-NOT: call
58+
; CHECK: ret void
59+
define void @test4_no_fold(i32 %a, i32 %b) {
60+
%cmp1 = icmp eq i32 %a, %b
61+
br i1 %cmp1, label %taken, label %untaken
62+
63+
taken:
64+
%cmp2 = icmp ugt i32 %a, %b
65+
br i1 %cmp2, label %else, label %untaken
66+
67+
else:
68+
call void @foo()
69+
ret void
70+
71+
untaken:
72+
ret void
73+
}
74+
75+
declare void @foo()
2876

2977
; PR5795
3078
define void @test5(i32 %A) {

0 commit comments

Comments
 (0)
Please sign in to comment.