OSDN Git Service

Update aosp/master LLVM for rebase to r256229
[android-x86/external-llvm.git] / test / Transforms / SimplifyCFG / merge-cond-stores.ll
1 ; RUN: opt -simplifycfg -instcombine < %s -simplifycfg-merge-cond-stores=true -simplifycfg-merge-cond-stores-aggressively=false -phi-node-folding-threshold=2 -S | FileCheck %s
2
3 ; CHECK-LABEL: @test_simple
4 ; This test should succeed and end up if-converted.
5 ; CHECK: icmp eq i32 %b, 0
6 ; CHECK-NEXT: icmp ne i32 %a, 0
7 ; CHECK-NEXT: xor i1 %x2, true
8 ; CHECK-NEXT: %[[x:.*]] = or i1 %{{.*}}, %{{.*}}
9 ; CHECK-NEXT: br i1 %[[x]]
10 ; CHECK: store
11 ; CHECK-NOT: store
12 ; CHECK: ret
13 define void @test_simple(i32* %p, i32 %a, i32 %b) {
14 entry:
15   %x1 = icmp eq i32 %a, 0
16   br i1 %x1, label %fallthrough, label %yes1
17
18 yes1:
19   store i32 0, i32* %p
20   br label %fallthrough
21
22 fallthrough:
23   %x2 = icmp eq i32 %b, 0
24   br i1 %x2, label %end, label %yes2
25
26 yes2:
27   store i32 1, i32* %p
28   br label %end
29
30 end:
31   ret void
32 }
33
34 ; CHECK-LABEL: @test_recursive
35 ; This test should entirely fold away, leaving one large basic block.
36 ; CHECK: store
37 ; CHECK-NOT: store
38 ; CHECK: ret
39 define void @test_recursive(i32* %p, i32 %a, i32 %b, i32 %c, i32 %d) {
40 entry:
41   %x1 = icmp eq i32 %a, 0
42   br i1 %x1, label %fallthrough, label %yes1
43
44 yes1:
45   store i32 0, i32* %p
46   br label %fallthrough
47
48 fallthrough:
49   %x2 = icmp eq i32 %b, 0
50   br i1 %x2, label %next, label %yes2
51
52 yes2:
53   store i32 1, i32* %p
54   br label %next
55
56 next:
57   %x3 = icmp eq i32 %c, 0
58   br i1 %x3, label %fallthrough2, label %yes3
59
60 yes3:
61   store i32 2, i32* %p
62   br label %fallthrough2
63
64 fallthrough2:
65   %x4 = icmp eq i32 %d, 0
66   br i1 %x4, label %end, label %yes4
67
68 yes4:
69   store i32 3, i32* %p
70   br label %end
71
72
73 end:
74   ret void
75 }
76
77 ; CHECK-LABEL: @test_not_ifconverted
78 ; The code in each diamond is too large - it won't be if-converted so our
79 ; heuristics should say no.
80 ; CHECK: store
81 ; CHECK: store
82 ; CHECK: ret
83 define void @test_not_ifconverted(i32* %p, i32 %a, i32 %b) {
84 entry:
85   %x1 = icmp eq i32 %a, 0
86   br i1 %x1, label %fallthrough, label %yes1
87
88 yes1:
89   %y1 = or i32 %b, 55
90   %y2 = add i32 %y1, 24
91   %y3 = and i32 %y2, 67
92   store i32 %y3, i32* %p
93   br label %fallthrough
94
95 fallthrough:
96   %x2 = icmp eq i32 %b, 0
97   br i1 %x2, label %end, label %yes2
98
99 yes2:
100   %z1 = or i32 %a, 55
101   %z2 = add i32 %z1, 24
102   %z3 = and i32 %z2, 67
103   store i32 %z3, i32* %p
104   br label %end
105
106 end:
107   ret void
108 }
109
110 ; CHECK-LABEL: @test_aliasing1
111 ; The store to %p clobbers the previous store, so if-converting this would
112 ; be illegal.
113 ; CHECK: store
114 ; CHECK: store
115 ; CHECK: ret
116 define void @test_aliasing1(i32* %p, i32 %a, i32 %b) {
117 entry:
118   %x1 = icmp eq i32 %a, 0
119   br i1 %x1, label %fallthrough, label %yes1
120
121 yes1:
122   store i32 0, i32* %p
123   br label %fallthrough
124
125 fallthrough:
126   %y1 = load i32, i32* %p
127   %x2 = icmp eq i32 %y1, 0
128   br i1 %x2, label %end, label %yes2
129
130 yes2:
131   store i32 1, i32* %p
132   br label %end
133
134 end:
135   ret void
136 }
137
138 ; CHECK-LABEL: @test_aliasing2
139 ; The load from %q aliases with %p, so if-converting this would be illegal.
140 ; CHECK: store
141 ; CHECK: store
142 ; CHECK: ret
143 define void @test_aliasing2(i32* %p, i32* %q, i32 %a, i32 %b) {
144 entry:
145   %x1 = icmp eq i32 %a, 0
146   br i1 %x1, label %fallthrough, label %yes1
147
148 yes1:
149   store i32 0, i32* %p
150   br label %fallthrough
151
152 fallthrough:
153   %y1 = load i32, i32* %q
154   %x2 = icmp eq i32 %y1, 0
155   br i1 %x2, label %end, label %yes2
156
157 yes2:
158   store i32 1, i32* %p
159   br label %end
160
161 end:
162   ret void
163 }
164
165 declare void @f()
166
167 ; CHECK-LABEL: @test_diamond_simple
168 ; This should get if-converted.
169 ; CHECK: store
170 ; CHECK-NOT: store
171 ; CHECK: ret
172 define i32 @test_diamond_simple(i32* %p, i32* %q, i32 %a, i32 %b) {
173 entry:
174   %x1 = icmp eq i32 %a, 0
175   br i1 %x1, label %no1, label %yes1
176
177 yes1:
178   store i32 0, i32* %p
179   br label %fallthrough
180
181 no1:
182   %z1 = add i32 %a, %b
183   br label %fallthrough
184
185 fallthrough:
186   %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
187   %x2 = icmp eq i32 %b, 0
188   br i1 %x2, label %no2, label %yes2
189
190 yes2:
191   store i32 1, i32* %p
192   br label %end
193
194 no2:
195   %z3 = sub i32 %z2, %b
196   br label %end
197
198 end:
199   %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
200   ret i32 %z4
201 }
202
203 ; CHECK-LABEL: @test_diamond_alias3
204 ; Now there is a call to f() in the bottom branch. The store in the first
205 ; branch would now be reordered with respect to the call if we if-converted,
206 ; so we must not.
207 ; CHECK: store
208 ; CHECK: store
209 ; CHECK: ret
210 define i32 @test_diamond_alias3(i32* %p, i32* %q, i32 %a, i32 %b) {
211 entry:
212   %x1 = icmp eq i32 %a, 0
213   br i1 %x1, label %no1, label %yes1
214
215 yes1:
216   store i32 0, i32* %p
217   br label %fallthrough
218
219 no1:
220   call void @f()
221   %z1 = add i32 %a, %b
222   br label %fallthrough
223
224 fallthrough:
225   %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
226   %x2 = icmp eq i32 %b, 0
227   br i1 %x2, label %no2, label %yes2
228
229 yes2:
230   store i32 1, i32* %p
231   br label %end
232
233 no2:
234   call void @f()
235   %z3 = sub i32 %z2, %b
236   br label %end
237
238 end:
239   %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
240   ret i32 %z4
241 }