[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / Transforms / GVN / PRE / pre-load.ll
blob1d050f4b6200f574ab6d2e31bdba293fcf132480
1 ; RUN: opt < %s -basicaa -gvn -enable-load-pre -S | FileCheck %s
2 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
4 define i32 @test1(i32* %p, i1 %C) {
5 ; CHECK-LABEL: @test1(
6 block1:
7         br i1 %C, label %block2, label %block3
9 block2:
10  br label %block4
11 ; CHECK: block2:
12 ; CHECK-NEXT: load i32, i32* %p
14 block3:
15   store i32 0, i32* %p
16   br label %block4
18 block4:
19   %PRE = load i32, i32* %p
20   ret i32 %PRE
21 ; CHECK: block4:
22 ; CHECK-NEXT: phi i32
23 ; CHECK-NEXT: ret i32
26 ; This is a simple phi translation case.
27 define i32 @test2(i32* %p, i32* %q, i1 %C) {
28 ; CHECK-LABEL: @test2(
29 block1:
30         br i1 %C, label %block2, label %block3
32 block2:
33  br label %block4
34 ; CHECK: block2:
35 ; CHECK-NEXT: load i32, i32* %q
37 block3:
38   store i32 0, i32* %p
39   br label %block4
41 block4:
42   %P2 = phi i32* [%p, %block3], [%q, %block2]
43   %PRE = load i32, i32* %P2
44   ret i32 %PRE
45 ; CHECK: block4:
46 ; CHECK-NEXT: phi i32 [
47 ; CHECK-NOT: load
48 ; CHECK: ret i32
51 ; This is a PRE case that requires phi translation through a GEP.
52 define i32 @test3(i32* %p, i32* %q, i32** %Hack, i1 %C) {
53 ; CHECK-LABEL: @test3(
54 block1:
55   %B = getelementptr i32, i32* %q, i32 1
56   store i32* %B, i32** %Hack
57         br i1 %C, label %block2, label %block3
59 block2:
60  br label %block4
61 ; CHECK: block2:
62 ; CHECK-NEXT: load i32, i32* %B
64 block3:
65   %A = getelementptr i32, i32* %p, i32 1
66   store i32 0, i32* %A
67   br label %block4
69 block4:
70   %P2 = phi i32* [%p, %block3], [%q, %block2]
71   %P3 = getelementptr i32, i32* %P2, i32 1
72   %PRE = load i32, i32* %P3
73   ret i32 %PRE
74 ; CHECK: block4:
75 ; CHECK: phi i32 [
76 ; CHECK-NOT: load
77 ; CHECK: ret i32
80 ;; Here the loaded address is available, but the computation is in 'block3'
81 ;; which does not dominate 'block2'.
82 define i32 @test4(i32* %p, i32* %q, i32** %Hack, i1 %C) {
83 ; CHECK-LABEL: @test4(
84 block1:
85         br i1 %C, label %block2, label %block3
87 block2:
88  br label %block4
89 ; CHECK: block2:
90 ; CHECK:   load i32, i32*
91 ; CHECK:   br label %block4
93 block3:
94   %B = getelementptr i32, i32* %q, i32 1
95   store i32* %B, i32** %Hack
97   %A = getelementptr i32, i32* %p, i32 1
98   store i32 0, i32* %A
99   br label %block4
101 block4:
102   %P2 = phi i32* [%p, %block3], [%q, %block2]
103   %P3 = getelementptr i32, i32* %P2, i32 1
104   %PRE = load i32, i32* %P3
105   ret i32 %PRE
106 ; CHECK: block4:
107 ; CHECK: phi i32 [
108 ; CHECK-NOT: load
109 ; CHECK: ret i32
112 ;void test5(int N, double *G) {
113 ;  int j;
114 ;  for (j = 0; j < N - 1; j++)
115 ;    G[j] = G[j] + G[j+1];
118 define void @test5(i32 %N, double* nocapture %G) nounwind ssp {
119 ; CHECK-LABEL: @test5(
120 entry:
121   %0 = add i32 %N, -1           
122   %1 = icmp sgt i32 %0, 0       
123   br i1 %1, label %bb.nph, label %return
125 bb.nph:                         
126   %tmp = zext i32 %0 to i64     
127   br label %bb
129 ; CHECK: bb.nph:
130 ; CHECK: load double, double*
131 ; CHECK: br label %bb
133 bb:             
134   %indvar = phi i64 [ 0, %bb.nph ], [ %tmp6, %bb ]
135   %tmp6 = add i64 %indvar, 1                    
136   %scevgep = getelementptr double, double* %G, i64 %tmp6
137   %scevgep7 = getelementptr double, double* %G, i64 %indvar
138   %2 = load double, double* %scevgep7, align 8
139   %3 = load double, double* %scevgep, align 8 
140   %4 = fadd double %2, %3             
141   store double %4, double* %scevgep7, align 8
142   %exitcond = icmp eq i64 %tmp6, %tmp 
143   br i1 %exitcond, label %return, label %bb
145 ; Should only be one load in the loop.
146 ; CHECK: bb:
147 ; CHECK: load double, double*
148 ; CHECK-NOT: load double, double*
149 ; CHECK: br i1 %exitcond
151 return:                               
152   ret void
155 ;void test6(int N, double *G) {
156 ;  int j;
157 ;  for (j = 0; j < N - 1; j++)
158 ;    G[j+1] = G[j] + G[j+1];
161 define void @test6(i32 %N, double* nocapture %G) nounwind ssp {
162 ; CHECK-LABEL: @test6(
163 entry:
164   %0 = add i32 %N, -1           
165   %1 = icmp sgt i32 %0, 0       
166   br i1 %1, label %bb.nph, label %return
168 bb.nph:                         
169   %tmp = zext i32 %0 to i64     
170   br label %bb
172 ; CHECK: bb.nph:
173 ; CHECK: load double, double*
174 ; CHECK: br label %bb
176 bb:             
177   %indvar = phi i64 [ 0, %bb.nph ], [ %tmp6, %bb ]
178   %tmp6 = add i64 %indvar, 1                    
179   %scevgep = getelementptr double, double* %G, i64 %tmp6
180   %scevgep7 = getelementptr double, double* %G, i64 %indvar
181   %2 = load double, double* %scevgep7, align 8
182   %3 = load double, double* %scevgep, align 8 
183   %4 = fadd double %2, %3             
184   store double %4, double* %scevgep, align 8
185   %exitcond = icmp eq i64 %tmp6, %tmp 
186   br i1 %exitcond, label %return, label %bb
188 ; Should only be one load in the loop.
189 ; CHECK: bb:
190 ; CHECK: load double, double*
191 ; CHECK-NOT: load double, double*
192 ; CHECK: br i1 %exitcond
194 return:                               
195   ret void
198 ;void test7(int N, double* G) {
199 ;  long j;
200 ;  G[1] = 1;
201 ;  for (j = 1; j < N - 1; j++)
202 ;      G[j+1] = G[j] + G[j+1];
205 ; This requires phi translation of the adds.
206 define void @test7(i32 %N, double* nocapture %G) nounwind ssp {
207 entry:
208   %0 = getelementptr inbounds double, double* %G, i64 1   
209   store double 1.000000e+00, double* %0, align 8
210   %1 = add i32 %N, -1                             
211   %2 = icmp sgt i32 %1, 1                         
212   br i1 %2, label %bb.nph, label %return
214 bb.nph:                                           
215   %tmp = sext i32 %1 to i64                       
216   %tmp7 = add i64 %tmp, -1                        
217   br label %bb
219 bb:                                               
220   %indvar = phi i64 [ 0, %bb.nph ], [ %tmp9, %bb ] 
221   %tmp8 = add i64 %indvar, 2                      
222   %scevgep = getelementptr double, double* %G, i64 %tmp8  
223   %tmp9 = add i64 %indvar, 1                      
224   %scevgep10 = getelementptr double, double* %G, i64 %tmp9 
225   %3 = load double, double* %scevgep10, align 8           
226   %4 = load double, double* %scevgep, align 8             
227   %5 = fadd double %3, %4                         
228   store double %5, double* %scevgep, align 8
229   %exitcond = icmp eq i64 %tmp9, %tmp7            
230   br i1 %exitcond, label %return, label %bb
232 ; Should only be one load in the loop.
233 ; CHECK: bb:
234 ; CHECK: load double, double*
235 ; CHECK-NOT: load double, double*
236 ; CHECK: br i1 %exitcond
238 return:                                           
239   ret void
242 ;; Here the loaded address isn't available in 'block2' at all, requiring a new
243 ;; GEP to be inserted into it.
244 define i32 @test8(i32* %p, i32* %q, i32** %Hack, i1 %C) {
245 ; CHECK-LABEL: @test8(
246 block1:
247         br i1 %C, label %block2, label %block3
249 block2:
250  br label %block4
251 ; CHECK: block2:
252 ; CHECK:   load i32, i32*
253 ; CHECK:   br label %block4
255 block3:
256   %A = getelementptr i32, i32* %p, i32 1
257   store i32 0, i32* %A
258   br label %block4
260 block4:
261   %P2 = phi i32* [%p, %block3], [%q, %block2]
262   %P3 = getelementptr i32, i32* %P2, i32 1
263   %PRE = load i32, i32* %P3
264   ret i32 %PRE
265 ; CHECK: block4:
266 ; CHECK: phi i32 [
267 ; CHECK-NOT: load
268 ; CHECK: ret i32
271 ;void test9(int N, double* G) {
272 ;  long j;
273 ;  for (j = 1; j < N - 1; j++)
274 ;      G[j+1] = G[j] + G[j+1];
277 ; This requires phi translation of the adds.
278 define void @test9(i32 %N, double* nocapture %G) nounwind ssp {
279 entry:
280   add i32 0, 0
281   %1 = add i32 %N, -1                             
282   %2 = icmp sgt i32 %1, 1                         
283   br i1 %2, label %bb.nph, label %return
285 bb.nph:                                           
286   %tmp = sext i32 %1 to i64                       
287   %tmp7 = add i64 %tmp, -1                        
288   br label %bb
290 ; CHECK: bb.nph:
291 ; CHECK:   load double, double*
292 ; CHECK:   br label %bb
294 bb:                                               
295   %indvar = phi i64 [ 0, %bb.nph ], [ %tmp9, %bb ] 
296   %tmp8 = add i64 %indvar, 2                      
297   %scevgep = getelementptr double, double* %G, i64 %tmp8  
298   %tmp9 = add i64 %indvar, 1                      
299   %scevgep10 = getelementptr double, double* %G, i64 %tmp9 
300   %3 = load double, double* %scevgep10, align 8           
301   %4 = load double, double* %scevgep, align 8             
302   %5 = fadd double %3, %4                         
303   store double %5, double* %scevgep, align 8
304   %exitcond = icmp eq i64 %tmp9, %tmp7            
305   br i1 %exitcond, label %return, label %bb
307 ; Should only be one load in the loop.
308 ; CHECK: bb:
309 ; CHECK: load double, double*
310 ; CHECK-NOT: load double, double*
311 ; CHECK: br i1 %exitcond
313 return:                                           
314   ret void
317 ;void test10(int N, double* G) {
318 ;  long j;
319 ;  for (j = 1; j < N - 1; j++)
320 ;      G[j] = G[j] + G[j+1] + G[j-1];
323 ; PR5501
324 define void @test10(i32 %N, double* nocapture %G) nounwind ssp {
325 entry:
326   %0 = add i32 %N, -1
327   %1 = icmp sgt i32 %0, 1
328   br i1 %1, label %bb.nph, label %return
330 bb.nph:
331   %tmp = sext i32 %0 to i64
332   %tmp8 = add i64 %tmp, -1
333   br label %bb
334 ; CHECK: bb.nph:
335 ; CHECK:   load double, double*
336 ; CHECK:   load double, double*
337 ; CHECK:   br label %bb
341   %indvar = phi i64 [ 0, %bb.nph ], [ %tmp11, %bb ]
342   %scevgep = getelementptr double, double* %G, i64 %indvar
343   %tmp9 = add i64 %indvar, 2
344   %scevgep10 = getelementptr double, double* %G, i64 %tmp9
345   %tmp11 = add i64 %indvar, 1
346   %scevgep12 = getelementptr double, double* %G, i64 %tmp11
347   %2 = load double, double* %scevgep12, align 8
348   %3 = load double, double* %scevgep10, align 8
349   %4 = fadd double %2, %3
350   %5 = load double, double* %scevgep, align 8
351   %6 = fadd double %4, %5
352   store double %6, double* %scevgep12, align 8
353   %exitcond = icmp eq i64 %tmp11, %tmp8
354   br i1 %exitcond, label %return, label %bb
356 ; Should only be one load in the loop.
357 ; CHECK: bb:
358 ; CHECK: load double, double*
359 ; CHECK-NOT: load double, double*
360 ; CHECK: br i1 %exitcond
362 return:
363   ret void
366 ; Test critical edge splitting.
367 define i32 @test11(i32* %p, i1 %C, i32 %N) {
368 ; CHECK-LABEL: @test11(
369 block1:
370         br i1 %C, label %block2, label %block3
372 block2:
373  %cond = icmp sgt i32 %N, 1
374  br i1 %cond, label %block4, label %block5
375 ; CHECK: load i32, i32* %p
376 ; CHECK-NEXT: br label %block4
378 block3:
379   store i32 0, i32* %p
380   br label %block4
382 block4:
383   %PRE = load i32, i32* %p
384   br label %block5
386 block5:
387   %ret = phi i32 [ 0, %block2 ], [ %PRE, %block4 ]
388   ret i32 %ret
389 ; CHECK: block4:
390 ; CHECK-NEXT: phi i32
393 declare void @f()
394 declare void @g(i32)
395 declare i32 @__CxxFrameHandler3(...)
397 ; Test that loads aren't PRE'd into EH pads.
398 define void @test12(i32* %p) personality i32 (...)* @__CxxFrameHandler3 {
399 ; CHECK-LABEL: @test12(
400 block1:
401   invoke void @f()
402           to label %block2 unwind label %catch.dispatch
404 block2:
405   invoke void @f()
406           to label %block3 unwind label %cleanup
408 block3:
409   ret void
411 catch.dispatch:
412   %cs1 = catchswitch within none [label %catch] unwind label %cleanup2
414 catch:
415   %c = catchpad within %cs1 []
416   catchret from %c to label %block2
418 cleanup:
419   %c1 = cleanuppad within none []
420   store i32 0, i32* %p
421   cleanupret from %c1 unwind label %cleanup2
423 ; CHECK: cleanup2:
424 ; CHECK-NOT: phi
425 ; CHECK-NEXT: %c2 = cleanuppad within none []
426 ; CHECK-NEXT: %NOTPRE = load i32, i32* %p
427 cleanup2:
428   %c2 = cleanuppad within none []
429   %NOTPRE = load i32, i32* %p
430   call void @g(i32 %NOTPRE)
431   cleanupret from %c2 unwind to caller
434 ; Don't PRE load across potentially throwing calls.
436 define i32 @test13(i32* noalias nocapture readonly %x, i32* noalias nocapture %r, i32 %a) {
438 ; CHECK-LABEL: @test13(
439 ; CHECK: entry:
440 ; CHECK-NEXT: icmp eq
441 ; CHECK-NEXT: br i1
443 entry:
444   %tobool = icmp eq i32 %a, 0
445   br i1 %tobool, label %if.end, label %if.then
447 ; CHECK: if.then:
448 ; CHECK-NEXT: load i32
449 ; CHECK-NEXT: store i32
451 if.then:
452   %uu = load i32, i32* %x, align 4
453   store i32 %uu, i32* %r, align 4
454   br label %if.end
456 ; CHECK: if.end:
457 ; CHECK-NEXT: call void @f()
458 ; CHECK-NEXT: load i32
460 if.end:
461   call void @f()
462   %vv = load i32, i32* %x, align 4
463   ret i32 %vv
466 ; Same as test13, but now the blocking function is not immediately in load's
467 ; block.
469 define i32 @test14(i32* noalias nocapture readonly %x, i32* noalias nocapture %r, i32 %a) {
471 ; CHECK-LABEL: @test14(
472 ; CHECK: entry:
473 ; CHECK-NEXT: icmp eq
474 ; CHECK-NEXT: br i1
476 entry:
477   %tobool = icmp eq i32 %a, 0
478   br i1 %tobool, label %if.end, label %if.then
480 ; CHECK: if.then:
481 ; CHECK-NEXT: load i32
482 ; CHECK-NEXT: store i32
484 if.then:
485   %uu = load i32, i32* %x, align 4
486   store i32 %uu, i32* %r, align 4
487   br label %if.end
489 ; CHECK: if.end:
490 ; CHECK-NEXT: call void @f()
491 ; CHECK-NEXT: load i32
493 if.end:
494   call void @f()
495   br label %follow_1
497 follow_1:
498   br label %follow_2
500 follow_2:
501   %vv = load i32, i32* %x, align 4
502   ret i32 %vv
505 ; Same as test13, but %x here is dereferenceable. A pointer that is
506 ; dereferenceable can be loaded from speculatively without a risk of trapping.
507 ; Since it is OK to speculate, PRE is allowed.
509 define i32 @test15(i32* noalias nocapture readonly dereferenceable(8) %x, i32* noalias nocapture %r, i32 %a) {
511 ; CHECK-LABEL: @test15
512 ; CHECK: entry:
513 ; CHECK-NEXT: icmp eq
514 ; CHECK-NEXT: br i1
516 entry:
517   %tobool = icmp eq i32 %a, 0
518   br i1 %tobool, label %if.end, label %if.then
520 ; CHECK: entry.if.end_crit_edge:
521 ; CHECK-NEXT: %vv.pre = load i32, i32* %x, align 4
522 ; CHECK-NEXT: br label %if.end
524 if.then:
525   %uu = load i32, i32* %x, align 4
526   store i32 %uu, i32* %r, align 4
527   br label %if.end
529 ; CHECK: if.then:
530 ; CHECK-NEXT: %uu = load i32, i32* %x, align 4
531 ; CHECK-NEXT: store i32 %uu, i32* %r, align 4
532 ; CHECK-NEXT: br label %if.end
534 if.end:
535   call void @f()
536   %vv = load i32, i32* %x, align 4
537   ret i32 %vv
539 ; CHECK: if.end:
540 ; CHECK-NEXT: %vv = phi i32 [ %vv.pre, %entry.if.end_crit_edge ], [ %uu, %if.then ]
541 ; CHECK-NEXT: call void @f()
542 ; CHECK-NEXT: ret i32 %vv
546 ; Same as test14, but %x here is dereferenceable. A pointer that is
547 ; dereferenceable can be loaded from speculatively without a risk of trapping.
548 ; Since it is OK to speculate, PRE is allowed.
550 define i32 @test16(i32* noalias nocapture readonly dereferenceable(8) %x, i32* noalias nocapture %r, i32 %a) {
552 ; CHECK-LABEL: @test16(
553 ; CHECK: entry:
554 ; CHECK-NEXT: icmp eq
555 ; CHECK-NEXT: br i1
557 entry:
558   %tobool = icmp eq i32 %a, 0
559   br i1 %tobool, label %if.end, label %if.then
561 ; CHECK: entry.if.end_crit_edge:
562 ; CHECK-NEXT: %vv.pre = load i32, i32* %x, align 4
563 ; CHECK-NEXT: br label %if.end
565 if.then:
566   %uu = load i32, i32* %x, align 4
567   store i32 %uu, i32* %r, align 4
568   br label %if.end
570 ; CHECK: if.then:
571 ; CHECK-NEXT: %uu = load i32, i32* %x, align 4
572 ; CHECK-NEXT: store i32 %uu, i32* %r, align 4
573 ; CHECK-NEXT: br label %if.end
575 if.end:
576   call void @f()
577   br label %follow_1
579 ; CHECK: if.end:
580 ; CHECK-NEXT: %vv = phi i32 [ %vv.pre, %entry.if.end_crit_edge ], [ %uu, %if.then ]
581 ; CHECK-NEXT: call void @f()
582 ; CHECK-NEXT: ret i32 %vv
584 follow_1:
585   br label %follow_2
587 follow_2:
588   %vv = load i32, i32* %x, align 4
589   ret i32 %vv