af025570b3c384f493ee70ee3c46e43a675a73d7
[oota-llvm.git] / test / Transforms / GVN / rle.ll
1 ; RUN: opt < %s -gvn -S | FileCheck %s
2
3 ; 32-bit little endian target.
4 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
5
6 ;; Trivial RLE test.
7 define i32 @test0(i32 %V, i32* %P) {
8   store i32 %V, i32* %P
9
10   %A = load i32* %P
11   ret i32 %A
12 ; CHECK: @test0
13 ; CHECK: ret i32 %V
14 }
15
16
17 ;;===----------------------------------------------------------------------===;;
18 ;; Tests for crashers
19 ;;===----------------------------------------------------------------------===;;
20
21 ;; PR5016
22 define i8 @crash0({i32, i32} %A, {i32, i32}* %P) {
23   store {i32, i32} %A, {i32, i32}* %P
24   %X = bitcast {i32, i32}* %P to i8*
25   %Y = load i8* %X
26   ret i8 %Y
27 }
28
29
30 ;;===----------------------------------------------------------------------===;;
31 ;; Store -> Load  and  Load -> Load forwarding where src and dst are different
32 ;; types, but where the base pointer is a must alias.
33 ;;===----------------------------------------------------------------------===;;
34
35 ;; i32 -> f32 forwarding.
36 define float @coerce_mustalias1(i32 %V, i32* %P) {
37   store i32 %V, i32* %P
38    
39   %P2 = bitcast i32* %P to float*
40
41   %A = load float* %P2
42   ret float %A
43 ; CHECK: @coerce_mustalias1
44 ; CHECK-NOT: load
45 ; CHECK: ret float 
46 }
47
48 ;; i32* -> float forwarding.
49 define float @coerce_mustalias2(i32* %V, i32** %P) {
50   store i32* %V, i32** %P
51    
52   %P2 = bitcast i32** %P to float*
53
54   %A = load float* %P2
55   ret float %A
56 ; CHECK: @coerce_mustalias2
57 ; CHECK-NOT: load
58 ; CHECK: ret float 
59 }
60
61 ;; float -> i32* forwarding.
62 define i32* @coerce_mustalias3(float %V, float* %P) {
63   store float %V, float* %P
64    
65   %P2 = bitcast float* %P to i32**
66
67   %A = load i32** %P2
68   ret i32* %A
69 ; CHECK: @coerce_mustalias3
70 ; CHECK-NOT: load
71 ; CHECK: ret i32* 
72 }
73
74 ;; i32 -> f32 load forwarding.
75 define float @coerce_mustalias4(i32* %P, i1 %cond) {
76   %A = load i32* %P
77   
78   %P2 = bitcast i32* %P to float*
79   %B = load float* %P2
80   br i1 %cond, label %T, label %F
81 T:
82   ret float %B
83   
84 F:
85   %X = bitcast i32 %A to float
86   ret float %X
87
88 ; CHECK: @coerce_mustalias4
89 ; CHECK: %A = load i32* %P
90 ; CHECK-NOT: load
91 ; CHECK: ret float
92 ; CHECK: F:
93 }
94
95 ;; i32 -> i8 forwarding
96 define i8 @coerce_mustalias5(i32 %V, i32* %P) {
97   store i32 %V, i32* %P
98    
99   %P2 = bitcast i32* %P to i8*
100
101   %A = load i8* %P2
102   ret i8 %A
103 ; CHECK: @coerce_mustalias5
104 ; CHECK-NOT: load
105 ; CHECK: ret i8
106 }
107
108 ;; i64 -> float forwarding
109 define float @coerce_mustalias6(i64 %V, i64* %P) {
110   store i64 %V, i64* %P
111    
112   %P2 = bitcast i64* %P to float*
113
114   %A = load float* %P2
115   ret float %A
116 ; CHECK: @coerce_mustalias6
117 ; CHECK-NOT: load
118 ; CHECK: ret float
119 }
120
121 ;; i64 -> i8* (32-bit) forwarding
122 define i8* @coerce_mustalias7(i64 %V, i64* %P) {
123   store i64 %V, i64* %P
124    
125   %P2 = bitcast i64* %P to i8**
126
127   %A = load i8** %P2
128   ret i8* %A
129 ; CHECK: @coerce_mustalias7
130 ; CHECK-NOT: load
131 ; CHECK: ret i8*
132 }
133
134 ; memset -> i16 forwarding.
135 define signext i16 @memset_to_i16_local(i16* %A) nounwind ssp {
136 entry:
137   %conv = bitcast i16* %A to i8* 
138   tail call void @llvm.memset.i64(i8* %conv, i8 1, i64 200, i32 1)
139   %arrayidx = getelementptr inbounds i16* %A, i64 42
140   %tmp2 = load i16* %arrayidx
141   ret i16 %tmp2
142 ; CHECK: @memset_to_i16_local
143 ; CHECK-NOT: load
144 ; CHECK: ret i16 257
145 }
146
147 ; memset -> float forwarding.
148 define float @memset_to_float_local(float* %A, i8 %Val) nounwind ssp {
149 entry:
150   %conv = bitcast float* %A to i8*                ; <i8*> [#uses=1]
151   tail call void @llvm.memset.i64(i8* %conv, i8 %Val, i64 400, i32 1)
152   %arrayidx = getelementptr inbounds float* %A, i64 42 ; <float*> [#uses=1]
153   %tmp2 = load float* %arrayidx                   ; <float> [#uses=1]
154   ret float %tmp2
155 ; CHECK: @memset_to_float_local
156 ; CHECK-NOT: load
157 ; CHECK: zext
158 ; CHECK-NEXT: shl
159 ; CHECK-NEXT: or
160 ; CHECK-NEXT: shl
161 ; CHECK-NEXT: or
162 ; CHECK-NEXT: bitcast
163 ; CHECK-NEXT: ret float
164 }
165
166 ;; non-local memset -> i16 load forwarding.
167 define i16 @memset_to_i16_nonlocal0(i16* %P, i1 %cond) {
168   %P3 = bitcast i16* %P to i8*
169   br i1 %cond, label %T, label %F
170 T:
171   tail call void @llvm.memset.i64(i8* %P3, i8 1, i64 400, i32 1)
172   br label %Cont
173   
174 F:
175   tail call void @llvm.memset.i64(i8* %P3, i8 2, i64 400, i32 1)
176   br label %Cont
177
178 Cont:
179   %P2 = getelementptr i16* %P, i32 4
180   %A = load i16* %P2
181   ret i16 %A
182
183 ; CHECK: @memset_to_i16_nonlocal0
184 ; CHECK: Cont:
185 ; CHECK-NEXT:   %A = phi i16 [ 514, %F ], [ 257, %T ]
186 ; CHECK-NOT: load
187 ; CHECK: ret i16 %A
188 }
189
190
191 declare void @llvm.memset.i64(i8* nocapture, i8, i64, i32) nounwind
192
193
194
195
196 ;; non-local i32/float -> i8 load forwarding.
197 define i8 @coerce_mustalias_nonlocal0(i32* %P, i1 %cond) {
198   %P2 = bitcast i32* %P to float*
199   %P3 = bitcast i32* %P to i8*
200   br i1 %cond, label %T, label %F
201 T:
202   store i32 42, i32* %P
203   br label %Cont
204   
205 F:
206   store float 1.0, float* %P2
207   br label %Cont
208
209 Cont:
210   %A = load i8* %P3
211   ret i8 %A
212
213 ; CHECK: @coerce_mustalias_nonlocal0
214 ; CHECK: Cont:
215 ; CHECK:   %A = phi i8 [
216 ; CHECK-NOT: load
217 ; CHECK: ret i8 %A
218 }
219
220
221 ;; non-local i32/float -> i8 load forwarding.  This also tests that the "P3"
222 ;; bitcast equivalence can be properly phi translated.
223 define i8 @coerce_mustalias_nonlocal1(i32* %P, i1 %cond) {
224   %P2 = bitcast i32* %P to float*
225   br i1 %cond, label %T, label %F
226 T:
227   store i32 42, i32* %P
228   br label %Cont
229   
230 F:
231   store float 1.0, float* %P2
232   br label %Cont
233
234 Cont:
235   %P3 = bitcast i32* %P to i8*
236   %A = load i8* %P3
237   ret i8 %A
238
239 ;; FIXME: This is disabled because this caused a miscompile in the llvm-gcc
240 ;; bootstrap, see r82411
241 ;
242 ; HECK: @coerce_mustalias_nonlocal1
243 ; HECK: Cont:
244 ; HECK:   %A = phi i8 [
245 ; HECK-NOT: load
246 ; HECK: ret i8 %A
247 }
248
249
250 ;; non-local i32 -> i8 partial redundancy load forwarding.
251 define i8 @coerce_mustalias_pre0(i32* %P, i1 %cond) {
252   %P3 = bitcast i32* %P to i8*
253   br i1 %cond, label %T, label %F
254 T:
255   store i32 42, i32* %P
256   br label %Cont
257   
258 F:
259   br label %Cont
260
261 Cont:
262   %A = load i8* %P3
263   ret i8 %A
264
265 ; CHECK: @coerce_mustalias_pre0
266 ; CHECK: F:
267 ; CHECK:   load i8* %P3
268 ; CHECK: Cont:
269 ; CHECK:   %A = phi i8 [
270 ; CHECK-NOT: load
271 ; CHECK: ret i8 %A
272 }
273
274 ;;===----------------------------------------------------------------------===;;
275 ;; Store -> Load  and  Load -> Load forwarding where src and dst are different
276 ;; types, and the reload is an offset from the store pointer.
277 ;;===----------------------------------------------------------------------===;;
278
279 ;; i32 -> i8 forwarding.
280 ;; PR4216
281 define i8 @coerce_offset0(i32 %V, i32* %P) {
282   store i32 %V, i32* %P
283    
284   %P2 = bitcast i32* %P to i8*
285   %P3 = getelementptr i8* %P2, i32 2
286
287   %A = load i8* %P3
288   ret i8 %A
289 ; CHECK: @coerce_offset0
290 ; CHECK-NOT: load
291 ; CHECK: ret i8
292 }
293
294 ;; non-local i32/float -> i8 load forwarding.
295 define i8 @coerce_offset_nonlocal0(i32* %P, i1 %cond) {
296   %P2 = bitcast i32* %P to float*
297   %P3 = bitcast i32* %P to i8*
298   %P4 = getelementptr i8* %P3, i32 2
299   br i1 %cond, label %T, label %F
300 T:
301   store i32 42, i32* %P
302   br label %Cont
303   
304 F:
305   store float 1.0, float* %P2
306   br label %Cont
307
308 Cont:
309   %A = load i8* %P4
310   ret i8 %A
311
312 ; CHECK: @coerce_offset_nonlocal0
313 ; CHECK: Cont:
314 ; CHECK:   %A = phi i8 [
315 ; CHECK-NOT: load
316 ; CHECK: ret i8 %A
317 }
318
319
320 ;; non-local i32 -> i8 partial redundancy load forwarding.
321 define i8 @coerce_offset_pre0(i32* %P, i1 %cond) {
322   %P3 = bitcast i32* %P to i8*
323   %P4 = getelementptr i8* %P3, i32 2
324   br i1 %cond, label %T, label %F
325 T:
326   store i32 42, i32* %P
327   br label %Cont
328   
329 F:
330   br label %Cont
331
332 Cont:
333   %A = load i8* %P4
334   ret i8 %A
335
336 ; CHECK: @coerce_offset_pre0
337 ; CHECK: F:
338 ; CHECK:   load i8* %P4
339 ; CHECK: Cont:
340 ; CHECK:   %A = phi i8 [
341 ; CHECK-NOT: load
342 ; CHECK: ret i8 %A
343 }
344
345 define i32 @chained_load(i32** %p) {
346 block1:
347   %z = load i32** %p
348         br i1 true, label %block2, label %block3
349
350 block2:
351  %a = load i32** %p
352  br label %block4
353
354 block3:
355   %b = load i32** %p
356   br label %block4
357
358 block4:
359   %c = load i32** %p
360   %d = load i32* %c
361   ret i32 %d
362   
363 ; CHECK: @chained_load
364 ; CHECK: %z = load i32** %p
365 ; CHECK-NOT: load
366 ; CHECK: %d = load i32* %z
367 ; CHECK-NEXT: ret i32 %d
368 }
369
370
371 declare i1 @cond() readonly
372 declare i1 @cond2() readonly
373
374 define i32 @phi_trans2() {
375 entry:
376   %P = alloca i32, i32 400
377   br label %F1
378   
379 F1:
380   %A = phi i32 [1, %entry], [2, %F]
381   %cond2 = call i1 @cond()
382   br i1 %cond2, label %T1, label %TY
383   
384 T1:
385   %P2 = getelementptr i32* %P, i32 %A
386   %x = load i32* %P2
387   %cond = call i1 @cond2()
388   br i1 %cond, label %TX, label %F
389   
390 F:
391   %P3 = getelementptr i32* %P, i32 2
392   store i32 17, i32* %P3
393   
394   store i32 42, i32* %P2  ; Provides "P[A]".
395   br label %F1
396
397 TX:
398   ret i32 %x  ;; SHOULD NOT BE COMPILED TO 'ret i32 42'.
399 TY:
400   ret i32 0
401 }
402
403