use getPredicateOnEdge to fold comparisons through PHI nodes,
[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 ;; non-local i32/float -> i8 load forwarding.
135 define i8 @coerce_mustalias_nonlocal0(i32* %P, i1 %cond) {
136   %P2 = bitcast i32* %P to float*
137   %P3 = bitcast i32* %P to i8*
138   br i1 %cond, label %T, label %F
139 T:
140   store i32 42, i32* %P
141   br label %Cont
142   
143 F:
144   store float 1.0, float* %P2
145   br label %Cont
146
147 Cont:
148   %A = load i8* %P3
149   ret i8 %A
150
151 ; CHECK: @coerce_mustalias_nonlocal0
152 ; CHECK: Cont:
153 ; CHECK:   %A = phi i8 [
154 ; CHECK-NOT: load
155 ; CHECK: ret i8 %A
156 }
157
158 ;; non-local i32/float -> i8 load forwarding.  This also tests that the "P3"
159 ;; bitcast equivalence can be properly phi translated.
160 define i8 @coerce_mustalias_nonlocal1(i32* %P, i1 %cond) {
161   %P2 = bitcast i32* %P to float*
162   br i1 %cond, label %T, label %F
163 T:
164   store i32 42, i32* %P
165   br label %Cont
166   
167 F:
168   store float 1.0, float* %P2
169   br label %Cont
170
171 Cont:
172   %P3 = bitcast i32* %P to i8*
173   %A = load i8* %P3
174   ret i8 %A
175
176 ;; FIXME: This is disabled because this caused a miscompile in the llvm-gcc
177 ;; bootstrap, see r82411
178 ;
179 ; HECK: @coerce_mustalias_nonlocal1
180 ; HECK: Cont:
181 ; HECK:   %A = phi i8 [
182 ; HECK-NOT: load
183 ; HECK: ret i8 %A
184 }
185
186
187 ;; non-local i32 -> i8 partial redundancy load forwarding.
188 define i8 @coerce_mustalias_pre0(i32* %P, i1 %cond) {
189   %P3 = bitcast i32* %P to i8*
190   br i1 %cond, label %T, label %F
191 T:
192   store i32 42, i32* %P
193   br label %Cont
194   
195 F:
196   br label %Cont
197
198 Cont:
199   %A = load i8* %P3
200   ret i8 %A
201
202 ; CHECK: @coerce_mustalias_pre0
203 ; CHECK: F:
204 ; CHECK:   load i8* %P3
205 ; CHECK: Cont:
206 ; CHECK:   %A = phi i8 [
207 ; CHECK-NOT: load
208 ; CHECK: ret i8 %A
209 }
210
211 ;;===----------------------------------------------------------------------===;;
212 ;; Store -> Load  and  Load -> Load forwarding where src and dst are different
213 ;; types, and the reload is an offset from the store pointer.
214 ;;===----------------------------------------------------------------------===;;
215
216 ;; i32 -> i8 forwarding.
217 ;; PR4216
218 define i8 @coerce_offset0(i32 %V, i32* %P) {
219   store i32 %V, i32* %P
220    
221   %P2 = bitcast i32* %P to i8*
222   %P3 = getelementptr i8* %P2, i32 2
223
224   %A = load i8* %P3
225   ret i8 %A
226 ; CHECK: @coerce_offset0
227 ; CHECK-NOT: load
228 ; CHECK: ret i8
229 }
230
231 ;; non-local i32/float -> i8 load forwarding.
232 define i8 @coerce_offset_nonlocal0(i32* %P, i1 %cond) {
233   %P2 = bitcast i32* %P to float*
234   %P3 = bitcast i32* %P to i8*
235   %P4 = getelementptr i8* %P3, i32 2
236   br i1 %cond, label %T, label %F
237 T:
238   store i32 42, i32* %P
239   br label %Cont
240   
241 F:
242   store float 1.0, float* %P2
243   br label %Cont
244
245 Cont:
246   %A = load i8* %P4
247   ret i8 %A
248
249 ; CHECK: @coerce_offset_nonlocal0
250 ; CHECK: Cont:
251 ; CHECK:   %A = phi i8 [
252 ; CHECK-NOT: load
253 ; CHECK: ret i8 %A
254 }
255
256
257 ;; non-local i32 -> i8 partial redundancy load forwarding.
258 define i8 @coerce_offset_pre0(i32* %P, i1 %cond) {
259   %P3 = bitcast i32* %P to i8*
260   %P4 = getelementptr i8* %P3, i32 2
261   br i1 %cond, label %T, label %F
262 T:
263   store i32 42, i32* %P
264   br label %Cont
265   
266 F:
267   br label %Cont
268
269 Cont:
270   %A = load i8* %P4
271   ret i8 %A
272
273 ; CHECK: @coerce_offset_pre0
274 ; CHECK: F:
275 ; CHECK:   load i8* %P4
276 ; CHECK: Cont:
277 ; CHECK:   %A = phi i8 [
278 ; CHECK-NOT: load
279 ; CHECK: ret i8 %A
280 }
281
282