teach GVN's load PRE to insert computations of the address in predecessors
[oota-llvm.git] / test / Transforms / GVN / pre-load.ll
1 ; RUN: opt < %s -gvn -enable-load-pre -S | FileCheck %s
2
3 define i32 @test1(i32* %p, i1 %C) {
4 ; CHECK: @test1
5 block1:
6         br i1 %C, label %block2, label %block3
7
8 block2:
9  br label %block4
10 ; CHECK: block2:
11 ; CHECK-NEXT: load i32* %p
12
13 block3:
14   store i32 0, i32* %p
15   br label %block4
16
17 block4:
18   %PRE = load i32* %p
19   ret i32 %PRE
20 ; CHECK: block4:
21 ; CHECK-NEXT: phi i32
22 ; CHECK-NEXT: ret i32
23 }
24
25 ; This is a simple phi translation case.
26 define i32 @test2(i32* %p, i32* %q, i1 %C) {
27 ; CHECK: @test2
28 block1:
29         br i1 %C, label %block2, label %block3
30
31 block2:
32  br label %block4
33 ; CHECK: block2:
34 ; CHECK-NEXT: load i32* %q
35
36 block3:
37   store i32 0, i32* %p
38   br label %block4
39
40 block4:
41   %P2 = phi i32* [%p, %block3], [%q, %block2]
42   %PRE = load i32* %P2
43   ret i32 %PRE
44 ; CHECK: block4:
45 ; CHECK-NEXT: phi i32 [
46 ; CHECK-NOT: load
47 ; CHECK: ret i32
48 }
49
50 ; This is a PRE case that requires phi translation through a GEP.
51 define i32 @test3(i32* %p, i32* %q, i32** %Hack, i1 %C) {
52 ; CHECK: @test3
53 block1:
54   %B = getelementptr i32* %q, i32 1
55   store i32* %B, i32** %Hack
56         br i1 %C, label %block2, label %block3
57
58 block2:
59  br label %block4
60 ; CHECK: block2:
61 ; CHECK-NEXT: load i32* %B
62
63 block3:
64   %A = getelementptr i32* %p, i32 1
65   store i32 0, i32* %A
66   br label %block4
67
68 block4:
69   %P2 = phi i32* [%p, %block3], [%q, %block2]
70   %P3 = getelementptr i32* %P2, i32 1
71   %PRE = load i32* %P3
72   ret i32 %PRE
73 ; CHECK: block4:
74 ; CHECK-NEXT: phi i32 [
75 ; CHECK-NOT: load
76 ; CHECK: ret i32
77 }
78
79 ;; Here the loaded address is available, but the computation is in 'block3'
80 ;; which does not dominate 'block2'.
81 define i32 @test4(i32* %p, i32* %q, i32** %Hack, i1 %C) {
82 ; CHECK: @test4
83 block1:
84         br i1 %C, label %block2, label %block3
85
86 block2:
87  br label %block4
88 ; CHECK: block2:
89 ; CHECK:   load i32*
90 ; CHECK:   br label %block4
91
92 block3:
93   %B = getelementptr i32* %q, i32 1
94   store i32* %B, i32** %Hack
95
96   %A = getelementptr i32* %p, i32 1
97   store i32 0, i32* %A
98   br label %block4
99
100 block4:
101   %P2 = phi i32* [%p, %block3], [%q, %block2]
102   %P3 = getelementptr i32* %P2, i32 1
103   %PRE = load i32* %P3
104   ret i32 %PRE
105 ; CHECK: block4:
106 ; CHECK-NEXT: phi i32 [
107 ; CHECK-NOT: load
108 ; CHECK: ret i32
109 }