Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 88c3cbe

Browse files
author
Eli Friedman
committed
[SCCP] Don't use markForcedConstant on branch conditions.
It's more aggressive than we need to be, and leads to strange workarounds in other places like call return value inference. Instead, just directly mark an edge viable. Tests by Florian Hahn. Differential Revision: https://reviews.llvm.org/D49408 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337507 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 7e9afd4 commit 88c3cbe

File tree

4 files changed

+151
-74
lines changed

4 files changed

+151
-74
lines changed

lib/Transforms/Scalar/SCCP.cpp

Lines changed: 62 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,10 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
327327
return BBExecutable.count(BB);
328328
}
329329

330+
// isEdgeFeasible - Return true if the control flow edge from the 'From' basic
331+
// block to the 'To' basic block is currently feasible.
332+
bool isEdgeFeasible(BasicBlock *From, BasicBlock *To);
333+
330334
std::vector<LatticeVal> getStructLatticeValueFor(Value *V) const {
331335
std::vector<LatticeVal> StructValues;
332336
auto *STy = dyn_cast<StructType>(V->getType());
@@ -531,9 +535,9 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
531535

532536
/// markEdgeExecutable - Mark a basic block as executable, adding it to the BB
533537
/// work list if it is not already executable.
534-
void markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest) {
538+
bool markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest) {
535539
if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second)
536-
return; // This edge is already known to be executable!
540+
return false; // This edge is already known to be executable!
537541

538542
if (!MarkBlockExecutable(Dest)) {
539543
// If the destination is already executable, we just made an *edge*
@@ -545,16 +549,13 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
545549
for (PHINode &PN : Dest->phis())
546550
visitPHINode(PN);
547551
}
552+
return true;
548553
}
549554

550555
// getFeasibleSuccessors - Return a vector of booleans to indicate which
551556
// successors are reachable from a given terminator instruction.
552557
void getFeasibleSuccessors(TerminatorInst &TI, SmallVectorImpl<bool> &Succs);
553558

554-
// isEdgeFeasible - Return true if the control flow edge from the 'From' basic
555-
// block to the 'To' basic block is currently feasible.
556-
bool isEdgeFeasible(BasicBlock *From, BasicBlock *To);
557-
558559
// OperandChangedState - This method is invoked on all of the users of an
559560
// instruction that was just changed state somehow. Based on this
560561
// information, we need to update the specified user of this instruction.
@@ -705,61 +706,10 @@ void SCCPSolver::getFeasibleSuccessors(TerminatorInst &TI,
705706
// isEdgeFeasible - Return true if the control flow edge from the 'From' basic
706707
// block to the 'To' basic block is currently feasible.
707708
bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) {
708-
assert(BBExecutable.count(To) && "Dest should always be alive!");
709-
710-
// Make sure the source basic block is executable!!
711-
if (!BBExecutable.count(From)) return false;
712-
713-
// Check to make sure this edge itself is actually feasible now.
714-
TerminatorInst *TI = From->getTerminator();
715-
if (auto *BI = dyn_cast<BranchInst>(TI)) {
716-
if (BI->isUnconditional())
717-
return true;
718-
719-
LatticeVal BCValue = getValueState(BI->getCondition());
720-
721-
// Overdefined condition variables mean the branch could go either way,
722-
// undef conditions mean that neither edge is feasible yet.
723-
ConstantInt *CI = BCValue.getConstantInt();
724-
if (!CI)
725-
return !BCValue.isUnknown();
726-
727-
// Constant condition variables mean the branch can only go a single way.
728-
return BI->getSuccessor(CI->isZero()) == To;
729-
}
730-
731-
// Unwinding instructions successors are always executable.
732-
if (TI->isExceptional())
733-
return true;
734-
735-
if (auto *SI = dyn_cast<SwitchInst>(TI)) {
736-
if (SI->getNumCases() < 1)
737-
return true;
738-
739-
LatticeVal SCValue = getValueState(SI->getCondition());
740-
ConstantInt *CI = SCValue.getConstantInt();
741-
742-
if (!CI)
743-
return !SCValue.isUnknown();
744-
745-
return SI->findCaseValue(CI)->getCaseSuccessor() == To;
746-
}
747-
748-
// In case of indirect branch and its address is a blockaddress, we mark
749-
// the target as executable.
750-
if (auto *IBR = dyn_cast<IndirectBrInst>(TI)) {
751-
LatticeVal IBRValue = getValueState(IBR->getAddress());
752-
BlockAddress *Addr = IBRValue.getBlockAddress();
753-
754-
if (!Addr)
755-
return !IBRValue.isUnknown();
756-
757-
// At this point, the indirectbr is branching on a blockaddress.
758-
return Addr->getBasicBlock() == To;
759-
}
760-
761-
LLVM_DEBUG(dbgs() << "Unknown terminator instruction: " << *TI << '\n');
762-
llvm_unreachable("SCCP: Don't know how to handle this terminator!");
709+
// Check if we've called markEdgeExecutable on the edge yet. (We could
710+
// be more aggressive and try to consider edges which haven't been marked
711+
// yet, but there isn't any need.)
712+
return KnownFeasibleEdges.count(Edge(From, To));
763713
}
764714

765715
// visit Implementations - Something changed in this instruction, either an
@@ -1567,11 +1517,14 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
15671517
}
15681518

15691519
// Otherwise, it is a branch on a symbolic value which is currently
1570-
// considered to be undef. Handle this by forcing the input value to the
1571-
// branch to false.
1572-
markForcedConstant(BI->getCondition(),
1573-
ConstantInt::getFalse(TI->getContext()));
1574-
return true;
1520+
// considered to be undef. Make sure some edge is executable, so a
1521+
// branch on "undef" always flows somewhere.
1522+
// FIXME: Distinguish between dead code and an LLVM "undef" value.
1523+
BasicBlock *DefaultSuccessor = TI->getSuccessor(1);
1524+
if (markEdgeExecutable(&BB, DefaultSuccessor))
1525+
return true;
1526+
1527+
continue;
15751528
}
15761529

15771530
if (auto *IBR = dyn_cast<IndirectBrInst>(TI)) {
@@ -1592,11 +1545,15 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
15921545
}
15931546

15941547
// Otherwise, it is a branch on a symbolic value which is currently
1595-
// considered to be undef. Handle this by forcing the input value to the
1596-
// branch to the first successor.
1597-
markForcedConstant(IBR->getAddress(),
1598-
BlockAddress::get(IBR->getSuccessor(0)));
1599-
return true;
1548+
// considered to be undef. Make sure some edge is executable, so a
1549+
// branch on "undef" always flows somewhere.
1550+
// FIXME: IndirectBr on "undef" doesn't actually need to go anywhere:
1551+
// we can assume the branch has undefined behavior instead.
1552+
BasicBlock *DefaultSuccessor = IBR->getSuccessor(0);
1553+
if (markEdgeExecutable(&BB, DefaultSuccessor))
1554+
return true;
1555+
1556+
continue;
16001557
}
16011558

16021559
if (auto *SI = dyn_cast<SwitchInst>(TI)) {
@@ -1611,8 +1568,15 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
16111568
return true;
16121569
}
16131570

1614-
markForcedConstant(SI->getCondition(), SI->case_begin()->getCaseValue());
1615-
return true;
1571+
// Otherwise, it is a branch on a symbolic value which is currently
1572+
// considered to be undef. Make sure some edge is executable, so a
1573+
// branch on "undef" always flows somewhere.
1574+
// FIXME: Distinguish between dead code and an LLVM "undef" value.
1575+
BasicBlock *DefaultSuccessor = SI->case_begin()->getCaseSuccessor();
1576+
if (markEdgeExecutable(&BB, DefaultSuccessor))
1577+
return true;
1578+
1579+
continue;
16161580
}
16171581
}
16181582

@@ -1992,6 +1956,31 @@ bool llvm::runIPSCCP(Module &M, const DataLayout &DL,
19921956
if (!I) continue;
19931957

19941958
bool Folded = ConstantFoldTerminator(I->getParent());
1959+
if (!Folded) {
1960+
// If the branch can't be folded, we must have forced an edge
1961+
// for an indeterminate value. Force the terminator to fold
1962+
// to that edge.
1963+
Constant *C;
1964+
BasicBlock *Dest;
1965+
if (SwitchInst *SI = dyn_cast<SwitchInst>(I)) {
1966+
Dest = SI->case_begin()->getCaseSuccessor();
1967+
C = SI->case_begin()->getCaseValue();
1968+
} else if (BranchInst *BI = dyn_cast<BranchInst>(I)) {
1969+
Dest = BI->getSuccessor(1);
1970+
C = ConstantInt::getFalse(BI->getContext());
1971+
} else if (IndirectBrInst *IBR = dyn_cast<IndirectBrInst>(I)) {
1972+
Dest = IBR->getSuccessor(0);
1973+
C = BlockAddress::get(IBR->getSuccessor(0));
1974+
} else {
1975+
llvm_unreachable("Unexpected terminator instruction");
1976+
}
1977+
assert(Solver.isEdgeFeasible(I->getParent(), Dest) &&
1978+
"Didn't find feasible edge?");
1979+
(void)Dest;
1980+
1981+
I->setOperand(0, C);
1982+
Folded = ConstantFoldTerminator(I->getParent());
1983+
}
19951984
assert(Folded &&
19961985
"Expect TermInst on constantint or blockaddress to be folded");
19971986
(void) Folded;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt < %s -S -ipsccp | FileCheck %s
3+
4+
define void @main() {
5+
; CHECK-LABEL: @main(
6+
; CHECK: %call = call i1 @patatino(i1 undef)
7+
; CHECK-NEXT: ret void
8+
;
9+
%call = call i1 @patatino(i1 undef)
10+
ret void
11+
}
12+
13+
define internal i1 @patatino(i1 %a) {
14+
; CHECK-LABEL: define internal i1 @patatino(
15+
; CHECK-NEXT: br label [[ONFALSE:%.*]]
16+
; CHECK-EMPTY:
17+
; CHECK-NEXT: onfalse:
18+
; CHECK-NEXT: ret i1 undef
19+
br i1 %a, label %ontrue, label %onfalse
20+
ontrue:
21+
ret i1 false
22+
onfalse:
23+
ret i1 false
24+
}

test/Transforms/SCCP/ipsccp-phi-one-pred-dead.ll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ define void @test() {
77
; CHECK-NEXT: entry:
88
; CHECK-NEXT: br label %Flow5.pre
99
; CHECK: Flow6:
10-
; CHECK-NEXT: br label %end2
10+
; CHECK-NEXT: br i1 undef, label %end1, label %end2
1111
; CHECK: Flow5.pre:
1212
; CHECK-NEXT: br label %Flow5
1313
; CHECK: Flow5:
1414
; CHECK-NEXT: br label %Flow6
15+
; CHECK: end1:
16+
; CHECK-NEXT: unreachable
1517
; CHECK: end2:
1618
; CHECK-NEXT: unreachable
1719
;

test/Transforms/SCCP/return-zapped.ll

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
; RUN: opt < %s -S -ipsccp | FileCheck %s
2+
3+
; After the first round of Solver.Solve(), the return value of @testf still
4+
; undefined as we hit a branch on undef. Therefore the conditional branch on
5+
; @testf's return value in @bar is unknown. In ResolvedUndefsIn, we force the
6+
; false branch to be feasible. We later discover that @testf actually
7+
; returns true, so we end up with an unfolded "br i1 true".
8+
define void @test1() {
9+
; CHECK-LABEL: @test1(
10+
; CHECK-LABEL: if.then:
11+
; CHECK: [[CALL:%.+]] = call i1 @testf()
12+
; CHECK-NEXT: br i1 true, label %if.end, label %if.then
13+
;
14+
entry:
15+
br label %if.then
16+
if.then: ; preds = %entry, %if.then
17+
%foo = phi i32 [ 0, %entry], [ %next, %if.then]
18+
%next = add i32 %foo, 1
19+
%call = call i1 @testf()
20+
br i1 %call, label %if.end, label %if.then
21+
22+
if.end: ; preds = %if.then, %entry
23+
ret void
24+
}
25+
26+
define internal i1 @testf() {
27+
; CHECK-LABEL: define internal i1 @testf(
28+
; CHECK-NEXT: entry:
29+
; CHECK-NEXT: br label [[IF_END3:%.*]]
30+
; CHECK: if.end3:
31+
; CHECK-NEXT: ret i1 undef
32+
;
33+
entry:
34+
br i1 undef, label %if.then1, label %if.end3
35+
36+
if.then1: ; preds = %if.end
37+
br label %if.end3
38+
39+
if.end3: ; preds = %if.then1, %entry
40+
ret i1 true
41+
}
42+
43+
44+
; Call sites in unreachable blocks should not be a problem.
45+
; CHECK-LABEL: define i1 @test2() {
46+
; CHECK-NEXT: entry:
47+
; CHECK-NEXT: br label %if.end
48+
; CHECK-LABEL: if.end: ; preds = %entry
49+
; CHECK-NEXT: %call2 = call i1 @testf()
50+
; CHECK-NEXT: ret i1 true
51+
define i1 @test2() {
52+
entry:
53+
br label %if.end
54+
55+
if.then: ; preds = %entry, %if.then
56+
%call = call i1 @testf()
57+
br i1 %call, label %if.end, label %if.then
58+
59+
if.end: ; preds = %if.then, %entry
60+
%call2 = call i1 @testf()
61+
ret i1 %call2
62+
}

0 commit comments

Comments
 (0)