llvm.org GIT mirror llvm / f7b2a9d
Teach SimplifyCFG that (switch (select cond, X, Y)) is better expressed as a branch. Based on a patch by Alistair Lynn. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126647 91177308-0d34-0410-b5e6-96231b3b80d8 Frits van Bommel 8 years ago
2 changed file(s) with 164 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
17971797
17981798 EraseTerminatorInstAndDCECond(OldTerm);
17991799 return true;
1800 }
1801
1802 // SimplifySwitchOnSelect - Replaces
1803 // (switch (select cond, X, Y)) on constant X, Y
1804 // with a branch - conditional if X and Y lead to distinct BBs,
1805 // unconditional otherwise.
1806 static bool SimplifySwitchOnSelect(SwitchInst *SI, SelectInst *Select) {
1807 // Check for constant integer values in the select.
1808 ConstantInt *TrueVal = dyn_cast(Select->getTrueValue());
1809 ConstantInt *FalseVal = dyn_cast(Select->getFalseValue());
1810 if (!TrueVal || !FalseVal)
1811 return false;
1812
1813 // Find the relevant condition and destinations.
1814 Value *Condition = Select->getCondition();
1815 BasicBlock *TrueBB = SI->getSuccessor(SI->findCaseValue(TrueVal));
1816 BasicBlock *FalseBB = SI->getSuccessor(SI->findCaseValue(FalseVal));
1817
1818 // Perform the actual simplification.
1819 return SimplifyTerminatorOnSelect(SI, Condition, TrueBB, FalseBB);
18001820 }
18011821
18021822 // SimplifyIndirectBrOnSelect - Replaces
23082328 if (BasicBlock *OnlyPred = BB->getSinglePredecessor())
23092329 if (SimplifyEqualityComparisonWithOnlyPredecessor(SI, OnlyPred))
23102330 return SimplifyCFG(BB) | true;
2311
2331
2332 Value *Cond = SI->getCondition();
2333 if (SelectInst *Select = dyn_cast(Cond))
2334 if (SimplifySwitchOnSelect(SI, Select))
2335 return SimplifyCFG(BB) | true;
2336
23122337 // If the block only contains the switch, see if we can fold the block
23132338 // away into any preds.
23142339 BasicBlock::iterator BBI = BB->begin();
0 ; RUN: opt < %s -simplifycfg -S | FileCheck %s
1
2 ; Test basic folding to a conditional branch.
3 define i32 @foo(i64 %x, i64 %y) nounwind {
4 ; CHECK: @foo
5 entry:
6 %eq = icmp eq i64 %x, %y
7 br i1 %eq, label %b, label %switch
8 switch:
9 %lt = icmp slt i64 %x, %y
10 ; CHECK: br i1 %lt, label %a, label %b
11 %qux = select i1 %lt, i32 0, i32 2
12 switch i32 %qux, label %bees [
13 i32 0, label %a
14 i32 1, label %b
15 i32 2, label %b
16 ]
17 a:
18 tail call void @bees.a() nounwind
19 ret i32 1
20 ; CHECK: b:
21 ; CHECK-NEXT: %retval = phi i32 [ 0, %switch ], [ 2, %entry ]
22 b:
23 %retval = phi i32 [0, %switch], [0, %switch], [2, %entry]
24 tail call void @bees.b() nounwind
25 ret i32 %retval
26 ; CHECK-NOT: bees:
27 bees:
28 tail call void @llvm.trap() nounwind
29 unreachable
30 }
31
32 ; Test basic folding to an unconditional branch.
33 define i32 @bar(i64 %x, i64 %y) nounwind {
34 ; CHECK: @bar
35 entry:
36 ; CHECK-NEXT: entry:
37 ; CHECK-NEXT: tail call void @bees.a() nounwind
38 ; CHECK-NEXT: ret i32 0
39 %lt = icmp slt i64 %x, %y
40 %qux = select i1 %lt, i32 0, i32 2
41 switch i32 %qux, label %bees [
42 i32 0, label %a
43 i32 1, label %b
44 i32 2, label %a
45 ]
46 a:
47 %retval = phi i32 [0, %entry], [0, %entry], [1, %b]
48 tail call void @bees.a() nounwind
49 ret i32 0
50 b:
51 tail call void @bees.b() nounwind
52 br label %a
53 bees:
54 tail call void @llvm.trap() nounwind
55 unreachable
56 }
57
58 ; Test the edge case where both values from the select are the default case.
59 define void @bazz(i64 %x, i64 %y) nounwind {
60 ; CHECK: @bazz
61 entry:
62 ; CHECK-NEXT: entry:
63 ; CHECK-NEXT: tail call void @bees.b() nounwind
64 ; CHECK-NEXT: ret void
65 %lt = icmp slt i64 %x, %y
66 %qux = select i1 %lt, i32 10, i32 12
67 switch i32 %qux, label %b [
68 i32 0, label %a
69 i32 1, label %bees
70 i32 2, label %bees
71 ]
72 a:
73 tail call void @bees.a() nounwind
74 ret void
75 b:
76 tail call void @bees.b() nounwind
77 ret void
78 bees:
79 tail call void @llvm.trap()
80 unreachable
81 }
82
83 ; Test the edge case where both values from the select are equal.
84 define void @quux(i64 %x, i64 %y) nounwind {
85 ; CHECK: @quux
86 entry:
87 ; CHECK-NEXT: entry:
88 ; CHECK-NEXT: tail call void @bees.a() nounwind
89 ; CHECK-NEXT: ret void
90 %lt = icmp slt i64 %x, %y
91 %qux = select i1 %lt, i32 0, i32 0
92 switch i32 %qux, label %b [
93 i32 0, label %a
94 i32 1, label %bees
95 i32 2, label %bees
96 ]
97 a:
98 tail call void @bees.a() nounwind
99 ret void
100 b:
101 tail call void @bees.b() nounwind
102 ret void
103 bees:
104 tail call void @llvm.trap()
105 unreachable
106 }
107
108 ; A final test, for phi node munging.
109 define i32 @xyzzy(i64 %x, i64 %y) {
110 ; CHECK: @xyzzy
111 entry:
112 %eq = icmp eq i64 %x, %y
113 br i1 %eq, label %r, label %cont
114 cont:
115 ; CHECK: %lt = icmp slt i64 %x, %y
116 %lt = icmp slt i64 %x, %y
117 ; CHECK-NEXT: br i1 %lt, label %a, label %r
118 %qux = select i1 %lt, i32 0, i32 2
119 switch i32 %qux, label %bees [
120 i32 0, label %a
121 i32 1, label %r
122 i32 2, label %r
123 ]
124 r:
125 %val = phi i32 [0, %entry], [1, %cont], [1, %cont]
126 ret i32 %val
127 a:
128 ret i32 -1
129 ; CHECK-NOT: bees:
130 bees:
131 tail call void @llvm.trap()
132 unreachable
133 }
134
135 declare void @llvm.trap() nounwind noreturn
136 declare void @bees.a() nounwind
137 declare void @bees.b() nounwind