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