1 ; Test if the !invariant.load metadata is maintained by GVN.
2 ; RUN: opt -basicaa -gvn -S < %s | FileCheck %s
4 define i32 @test1(i32* nocapture %p, i8* nocapture %q) {
6 ; CHECK: %x = load i32, i32* %p, align 4, !invariant.load !0
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
17 define i32 @test2(i32* nocapture %p, i8* nocapture %q) {
19 ; CHECK-NOT: !invariant.load
20 ; CHECK-NOT: %y = load
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
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) {
36 %v1 = load i32, i32* %p
37 br i1 %cnd, label %bb1, label %bb2
44 %v2 = load i32, i32* %p, !invariant.load !0
45 %res = sub i32 %v1, %v2
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) {
53 ; %v2 is redundant, but GVN currently doesn't catch that
55 %v1 = load i32, i32* %p, !invariant.load !0
56 br i1 %cnd, label %bb1, label %bb2
63 %v2 = load i32, i32* %p
64 %res = sub i32 %v1, %v2
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) {
74 ; CHECK-NEXT: store i32 5, i32* %p
75 ; CHECK-NEXT: ret i32 5
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
86 ; Clobbering (mayalias) stores, even in function calls, can be ignored
87 define i32 @test6(i1 %cnd, i32* %p) {
91 ; CHECK-NEXT: ret i32 0
93 %v1 = load i32, i32* %p, !invariant.load !0
95 %v2 = load i32, i32* %p, !invariant.load !0
96 %res = sub i32 %v1, %v2
100 declare noalias i32* @bar(...)
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) {
106 ; CHECK-LABEL: entry:
108 ; CHECK-NEXT: ret i32 0
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
117 define i32 @test8(i1 %cnd, i32* %p) {
120 ; CHECK: load i32, i32* %p2, !invariant.load
121 ; CHECK: br label %merge
123 %v1 = load i32, i32* %p, !invariant.load !0
124 br i1 %cnd, label %taken, label %merge
126 %p2 = call i32* (...) @bar(i32* %p)
129 %p3 = phi i32* [%p, %entry], [%p2, %taken]
130 %v2 = load i32, i32* %p3, !invariant.load !0
131 %res = sub i32 %v1, %v2