Make simplifycfg reprocess newly formed "br (cond1 | cond2)" conditions
[oota-llvm.git] / test / Transforms / SimplifyCFG / switch_create.ll
1 ; RUN: opt < %s -simplifycfg -S | FileCheck %s
2
3 declare void @foo1()
4
5 declare void @foo2()
6
7 define void @test1(i32 %V) {
8         %C1 = icmp eq i32 %V, 4         ; <i1> [#uses=1]
9         %C2 = icmp eq i32 %V, 17                ; <i1> [#uses=1]
10         %CN = or i1 %C1, %C2            ; <i1> [#uses=1]
11         br i1 %CN, label %T, label %F
12 T:              ; preds = %0
13         call void @foo1( )
14         ret void
15 F:              ; preds = %0
16         call void @foo2( )
17         ret void
18 ; CHECK: @test1
19 ; CHECK:  switch i32 %V, label %F [
20 ; CHECK:    i32 17, label %T
21 ; CHECK:    i32 4, label %T
22 ; CHECK:  ]
23 }
24
25 define void @test2(i32 %V) {
26         %C1 = icmp ne i32 %V, 4         ; <i1> [#uses=1]
27         %C2 = icmp ne i32 %V, 17                ; <i1> [#uses=1]
28         %CN = and i1 %C1, %C2           ; <i1> [#uses=1]
29         br i1 %CN, label %T, label %F
30 T:              ; preds = %0
31         call void @foo1( )
32         ret void
33 F:              ; preds = %0
34         call void @foo2( )
35         ret void
36 ; CHECK: @test2
37 ; CHECK:  switch i32 %V, label %T [
38 ; CHECK:    i32 17, label %F
39 ; CHECK:    i32 4, label %F
40 ; CHECK:  ]
41 }
42
43 define void @test3(i32 %V) {
44         %C1 = icmp eq i32 %V, 4         ; <i1> [#uses=1]
45         br i1 %C1, label %T, label %N
46 N:              ; preds = %0
47         %C2 = icmp eq i32 %V, 17                ; <i1> [#uses=1]
48         br i1 %C2, label %T, label %F
49 T:              ; preds = %N, %0
50         call void @foo1( )
51         ret void
52 F:              ; preds = %N
53         call void @foo2( )
54         ret void
55
56 ; CHECK: @test3
57 ; CHECK: switch i32 %V, label %F [
58 ; CHECK:     i32 4, label %T
59 ; CHECK:     i32 17, label %T
60 ; CHECK:   ]
61 }
62
63
64
65 define i32 @test4(i8 zeroext %c) nounwind ssp noredzone {
66 entry:
67   %cmp = icmp eq i8 %c, 62
68   br i1 %cmp, label %lor.end, label %lor.lhs.false
69
70 lor.lhs.false:                                    ; preds = %entry
71   %cmp4 = icmp eq i8 %c, 34
72   br i1 %cmp4, label %lor.end, label %lor.rhs
73
74 lor.rhs:                                          ; preds = %lor.lhs.false
75   %cmp8 = icmp eq i8 %c, 92
76   br label %lor.end
77
78 lor.end:                                          ; preds = %lor.rhs, %lor.lhs.false, %entry
79   %0 = phi i1 [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp8, %lor.rhs ]
80   %lor.ext = zext i1 %0 to i32
81   ret i32 %lor.ext
82   
83 ; CHECK: @test4
84 ; CHECK:  switch i8 %c, label %lor.rhs [
85 ; CHECK:    i8 62, label %lor.end
86 ; CHECK:    i8 34, label %lor.end
87 ; CHECK:    i8 92, label %lor.end
88 ; CHECK:  ]
89 }
90
91 define i32 @test5(i8 zeroext %c) nounwind ssp noredzone {
92 entry:
93   switch i8 %c, label %lor.rhs [
94     i8 62, label %lor.end
95     i8 34, label %lor.end
96     i8 92, label %lor.end
97   ]
98
99 lor.rhs:                                          ; preds = %entry
100   %V = icmp eq i8 %c, 92
101   br label %lor.end
102
103 lor.end:                                          ; preds = %entry, %entry, %entry, %lor.rhs
104   %0 = phi i1 [ true, %entry ], [ %V, %lor.rhs ], [ true, %entry ], [ true, %entry ]
105   %lor.ext = zext i1 %0 to i32
106   ret i32 %lor.ext
107 ; CHECK: @test5
108 ; CHECK:  switch i8 %c, label %lor.rhs [
109 ; CHECK:    i8 62, label %lor.end
110 ; CHECK:    i8 34, label %lor.end
111 ; CHECK:    i8 92, label %lor.end
112 ; CHECK:  ]
113 }
114
115
116 define i1 @test6({ i32, i32 }* %I) {
117 entry:
118         %tmp.1.i = getelementptr { i32, i32 }* %I, i64 0, i32 1         ; <i32*> [#uses=1]
119         %tmp.2.i = load i32* %tmp.1.i           ; <i32> [#uses=6]
120         %tmp.2 = icmp eq i32 %tmp.2.i, 14               ; <i1> [#uses=1]
121         br i1 %tmp.2, label %shortcirc_done.4, label %shortcirc_next.0
122 shortcirc_next.0:               ; preds = %entry
123         %tmp.6 = icmp eq i32 %tmp.2.i, 15               ; <i1> [#uses=1]
124         br i1 %tmp.6, label %shortcirc_done.4, label %shortcirc_next.1
125 shortcirc_next.1:               ; preds = %shortcirc_next.0
126         %tmp.11 = icmp eq i32 %tmp.2.i, 16              ; <i1> [#uses=1]
127         br i1 %tmp.11, label %shortcirc_done.4, label %shortcirc_next.2
128 shortcirc_next.2:               ; preds = %shortcirc_next.1
129         %tmp.16 = icmp eq i32 %tmp.2.i, 17              ; <i1> [#uses=1]
130         br i1 %tmp.16, label %shortcirc_done.4, label %shortcirc_next.3
131 shortcirc_next.3:               ; preds = %shortcirc_next.2
132         %tmp.21 = icmp eq i32 %tmp.2.i, 18              ; <i1> [#uses=1]
133         br i1 %tmp.21, label %shortcirc_done.4, label %shortcirc_next.4
134 shortcirc_next.4:               ; preds = %shortcirc_next.3
135         %tmp.26 = icmp eq i32 %tmp.2.i, 19              ; <i1> [#uses=1]
136         br label %UnifiedReturnBlock
137 shortcirc_done.4:               ; preds = %shortcirc_next.3, %shortcirc_next.2, %shortcirc_next.1, %shortcirc_next.0, %entry
138         br label %UnifiedReturnBlock
139 UnifiedReturnBlock:             ; preds = %shortcirc_done.4, %shortcirc_next.4
140         %UnifiedRetVal = phi i1 [ %tmp.26, %shortcirc_next.4 ], [ true, %shortcirc_done.4 ]             ; <i1> [#uses=1]
141         ret i1 %UnifiedRetVal
142         
143 ; CHECK: @test6
144 ; CHECK:   switch i32 %tmp.2.i, label %shortcirc_next.4 [
145 ; CHECK:       i32 14, label %UnifiedReturnBlock
146 ; CHECK:       i32 15, label %UnifiedReturnBlock
147 ; CHECK:       i32 16, label %UnifiedReturnBlock
148 ; CHECK:       i32 17, label %UnifiedReturnBlock
149 ; CHECK:       i32 18, label %UnifiedReturnBlock
150 ; CHECK:       i32 19, label %switch.edge
151 ; CHECK:     ]
152 }
153
154 define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone {
155 entry:
156   %cmp = icmp ult i32 %x, 32
157   %cmp4 = icmp eq i8 %c, 97
158   %or.cond = or i1 %cmp, %cmp4
159   %cmp9 = icmp eq i8 %c, 99
160   %or.cond11 = or i1 %or.cond, %cmp9
161   br i1 %or.cond11, label %if.then, label %if.end
162
163 if.then:                                          ; preds = %entry
164   tail call void @foo1() nounwind noredzone
165   ret void
166
167 if.end:                                           ; preds = %entry
168   ret void
169   
170 ; CHECK: @test7
171 ; CHECK:   %cmp = icmp ult i32 %x, 32
172 ; CHECK:   br i1 %cmp, label %if.then, label %switch.early.test
173 ; CHECK: switch.early.test:
174 ; CHECK:   switch i8 %c, label %if.end [
175 ; CHECK:     i8 99, label %if.then
176 ; CHECK:     i8 97, label %if.then
177 ; CHECK:   ]
178 }
179
180 define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone {
181 entry:
182   br i1 %C, label %N, label %if.then
183 N:
184   %cmp = icmp ult i32 %x, 32
185   %cmp4 = icmp eq i8 %c, 97
186   %or.cond = or i1 %cmp, %cmp4
187   %cmp9 = icmp eq i8 %c, 99
188   %or.cond11 = or i1 %or.cond, %cmp9
189   br i1 %or.cond11, label %if.then, label %if.end
190
191 if.then:                                          ; preds = %entry
192   %A = phi i32 [0, %entry], [42, %N]
193   tail call void @foo1() nounwind noredzone
194   ret i32 %A
195
196 if.end:                                           ; preds = %entry
197   ret i32 0
198   
199 ; CHECK: @test8
200 ; CHECK: switch.early.test:
201 ; CHECK:   switch i8 %c, label %if.end [
202 ; CHECK:     i8 99, label %if.then
203 ; CHECK:     i8 97, label %if.then
204 ; CHECK:   ]
205 ; CHECK:   %A = phi i32 [ 0, %entry ], [ 42, %switch.early.test ], [ 42, %N ], [ 42, %switch.early.test ]
206 }
207
208 define i32 @test9(i8 zeroext %c) nounwind ssp noredzone {
209 entry:
210   %cmp = icmp ult i8 %c, 33
211   br i1 %cmp, label %lor.end, label %lor.lhs.false
212
213 lor.lhs.false:                                    ; preds = %entry
214   %cmp4 = icmp eq i8 %c, 46
215   br i1 %cmp4, label %lor.end, label %lor.lhs.false6
216
217 lor.lhs.false6:                                   ; preds = %lor.lhs.false
218   %cmp9 = icmp eq i8 %c, 44
219   br i1 %cmp9, label %lor.end, label %lor.lhs.false11
220
221 lor.lhs.false11:                                  ; preds = %lor.lhs.false6
222   %cmp14 = icmp eq i8 %c, 58
223   br i1 %cmp14, label %lor.end, label %lor.lhs.false16
224
225 lor.lhs.false16:                                  ; preds = %lor.lhs.false11
226   %cmp19 = icmp eq i8 %c, 59
227   br i1 %cmp19, label %lor.end, label %lor.lhs.false21
228
229 lor.lhs.false21:                                  ; preds = %lor.lhs.false16
230   %cmp24 = icmp eq i8 %c, 60
231   br i1 %cmp24, label %lor.end, label %lor.lhs.false26
232
233 lor.lhs.false26:                                  ; preds = %lor.lhs.false21
234   %cmp29 = icmp eq i8 %c, 62
235   br i1 %cmp29, label %lor.end, label %lor.lhs.false31
236
237 lor.lhs.false31:                                  ; preds = %lor.lhs.false26
238   %cmp34 = icmp eq i8 %c, 34
239   br i1 %cmp34, label %lor.end, label %lor.lhs.false36
240
241 lor.lhs.false36:                                  ; preds = %lor.lhs.false31
242   %cmp39 = icmp eq i8 %c, 92
243   br i1 %cmp39, label %lor.end, label %lor.rhs
244
245 lor.rhs:                                          ; preds = %lor.lhs.false36
246   %cmp43 = icmp eq i8 %c, 39
247   br label %lor.end
248
249 lor.end:                                          ; preds = %lor.rhs, %lor.lhs.false36, %lor.lhs.false31, %lor.lhs.false26, %lor.lhs.false21, %lor.lhs.false16, %lor.lhs.false11, %lor.lhs.false6, %lor.lhs.false, %entry
250   %0 = phi i1 [ true, %lor.lhs.false36 ], [ true, %lor.lhs.false31 ], [ true, %lor.lhs.false26 ], [ true, %lor.lhs.false21 ], [ true, %lor.lhs.false16 ], [ true, %lor.lhs.false11 ], [ true, %lor.lhs.false6 ], [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp43, %lor.rhs ]
251   %conv46 = zext i1 %0 to i32
252   ret i32 %conv46
253   
254 ; CHECK: @test9
255 ; CHECK:   %cmp = icmp ult i8 %c, 33
256 ; CHECK:   br i1 %cmp, label %lor.end, label %switch.early.test
257
258 ; CHECK: switch.early.test:
259 ; CHECK:   switch i8 %c, label %lor.rhs [
260 ; CHECK:     i8 46, label %lor.end
261 ; CHECK:     i8 44, label %lor.end
262 ; CHECK:     i8 58, label %lor.end
263 ; CHECK:     i8 59, label %lor.end
264 ; CHECK:     i8 60, label %lor.end
265 ; CHECK:     i8 62, label %lor.end
266 ; CHECK:     i8 34, label %lor.end
267 ; CHECK:     i8 92, label %lor.end
268 ; CHECK:     i8 39, label %lor.end
269 ; CHECK:   ]
270 }
271
272