[opaque pointer type] Add textual IR support for explicit type parameter to the call...
[oota-llvm.git] / test / Transforms / GVN / invariant-load.ll
1 ; Test if the !invariant.load metadata is maintained by GVN.
2 ; RUN: opt -basicaa -gvn -S < %s | FileCheck %s
3
4 define i32 @test1(i32* nocapture %p, i8* nocapture %q) {
5 ; CHECK-LABEL: test1
6 ; CHECK: %x = load i32, i32* %p, align 4, !invariant.load !0
7 ; CHECK-NOT: %y = load
8 entry:
9   %x = load i32, i32* %p, align 4, !invariant.load !0
10   %conv = trunc i32 %x to i8
11   store i8 %conv, i8* %q, align 1
12   %y = load i32, i32* %p, align 4, !invariant.load !0
13   %add = add i32 %y, 1
14   ret i32 %add
15 }
16
17 define i32 @test2(i32* nocapture %p, i8* nocapture %q) {
18 ; CHECK-LABEL: test2
19 ; CHECK-NOT: !invariant.load
20 ; CHECK-NOT: %y = load
21 entry:
22   %x = load i32, i32* %p, align 4
23   %conv = trunc i32 %x to i8
24   store i8 %conv, i8* %q, align 1
25   %y = load i32, i32* %p, align 4, !invariant.load !0
26   %add = add i32 %y, 1
27   ret i32 %add
28 }
29
30 ; With the invariant.load metadata, what would otherwise
31 ; be a case for PRE becomes a full redundancy.
32 define i32 @test3(i1 %cnd, i32* %p, i32* %q) {
33 ; CHECK-LABEL: test3
34 ; CHECK-NOT: load
35 entry:
36   %v1 = load i32, i32* %p
37   br i1 %cnd, label %bb1, label %bb2
38
39 bb1:
40   store i32 5, i32* %q
41   br label %bb2
42
43 bb2:
44   %v2 = load i32, i32* %p, !invariant.load !0
45   %res = sub i32 %v1, %v2
46   ret i32 %res
47 }
48
49 ; This test is here to document a case which doesn't optimize
50 ; as well as it could.  
51 define i32 @test4(i1 %cnd, i32* %p, i32* %q) {
52 ; CHECK-LABEL: test4
53 ; %v2 is redundant, but GVN currently doesn't catch that
54 entry:
55   %v1 = load i32, i32* %p, !invariant.load !0
56   br i1 %cnd, label %bb1, label %bb2
57
58 bb1:
59   store i32 5, i32* %q
60   br label %bb2
61
62 bb2:
63   %v2 = load i32, i32* %p
64   %res = sub i32 %v1, %v2
65   ret i32 %res
66 }
67
68 ; Checks that we return the mustalias store as a def
69 ; so that it contributes to value forwarding.  Note
70 ; that we could and should remove the store too.
71 define i32 @test5(i1 %cnd, i32* %p) {
72 ; CHECK-LABEL: test5
73 ; CHECK-LABEL: entry:
74 ; CHECK-NEXT: store i32 5, i32* %p
75 ; CHECK-NEXT: ret i32 5
76 entry:
77   %v1 = load i32, i32* %p, !invariant.load !0
78   store i32 5, i32* %p ;; must alias store, want to exploit
79   %v2 = load i32, i32* %p, !invariant.load !0
80   ret i32 %v2
81 }
82
83
84 declare void @foo()
85
86 ; Clobbering (mayalias) stores, even in function calls, can be ignored
87 define i32 @test6(i1 %cnd, i32* %p) {
88 ; CHECK-LABEL: test6
89 ; CHECK-LABEL: entry:
90 ; CHECK-NEXT: @foo
91 ; CHECK-NEXT: ret i32 0
92 entry:
93   %v1 = load i32, i32* %p, !invariant.load !0
94   call void @foo()
95   %v2 = load i32, i32* %p, !invariant.load !0
96   %res = sub i32 %v1, %v2
97   ret i32 %res
98 }
99
100 declare noalias i32* @bar(...) 
101
102 ; Same as previous, but a function with a noalias result (since they're handled
103 ; differently in MDA)
104 define i32 @test7(i1 %cnd, i32* %p) {
105 ; CHECK-LABEL: test7
106 ; CHECK-LABEL: entry:
107 ; CHECK-NEXT: @bar
108 ; CHECK-NEXT: ret i32 0
109 entry:
110   %v1 = load i32, i32* %p, !invariant.load !0
111   call i32* (...) @bar(i32* %p)
112   %v2 = load i32, i32* %p, !invariant.load !0
113   %res = sub i32 %v1, %v2
114   ret i32 %res
115 }
116
117
118 !0 = !{ }
119