Use references to attribute groups on the call/invoke instructions.
[oota-llvm.git] / test / Transforms / ObjCARC / rle-s2l.ll
1 ; RUN: opt -S -basicaa -objc-arc < %s | FileCheck %s
2
3 declare i8* @objc_loadWeak(i8**)
4 declare i8* @objc_loadWeakRetained(i8**)
5 declare i8* @objc_storeWeak(i8**, i8*)
6 declare i8* @objc_initWeak(i8**, i8*)
7 declare void @use_pointer(i8*)
8 declare void @callee()
9
10 ; Basic redundant @objc_loadWeak elimination.
11
12 ; CHECK:      define void @test0(i8** %p) {
13 ; CHECK-NEXT:   %y = call i8* @objc_loadWeak(i8** %p)
14 ; CHECK-NEXT:   call void @use_pointer(i8* %y)
15 ; CHECK-NEXT:   ret void
16 ; CHECK-NEXT: }
17 define void @test0(i8** %p) {
18   %x = call i8* @objc_loadWeak(i8** %p)
19   %y = call i8* @objc_loadWeak(i8** %p)
20   call void @use_pointer(i8* %y)
21   ret void
22 }
23
24 ; DCE the @objc_loadWeak.
25
26 ; CHECK:      define void @test1(i8** %p) {
27 ; CHECK-NEXT:   %y = call i8* @objc_loadWeakRetained(i8** %p)
28 ; CHECK-NEXT:   call void @use_pointer(i8* %y)
29 ; CHECK-NEXT:   ret void
30 ; CHECK-NEXT: }
31 define void @test1(i8** %p) {
32   %x = call i8* @objc_loadWeak(i8** %p)
33   %y = call i8* @objc_loadWeakRetained(i8** %p)
34   call void @use_pointer(i8* %y)
35   ret void
36 }
37
38 ; Basic redundant @objc_loadWeakRetained elimination.
39
40 ; CHECK:      define void @test2(i8** %p) {
41 ; CHECK-NEXT:   %x = call i8* @objc_loadWeak(i8** %p)
42 ; CHECK-NEXT:   store i8 3, i8* %x
43 ; CHECK-NEXT:   %1 = tail call i8* @objc_retain(i8* %x)
44 ; CHECK-NEXT:   call void @use_pointer(i8* %x)
45 ; CHECK-NEXT:   ret void
46 ; CHECK-NEXT: }
47 define void @test2(i8** %p) {
48   %x = call i8* @objc_loadWeak(i8** %p)
49   store i8 3, i8* %x
50   %y = call i8* @objc_loadWeakRetained(i8** %p)
51   call void @use_pointer(i8* %y)
52   ret void
53 }
54
55 ; Basic redundant @objc_loadWeakRetained elimination, this time
56 ; with a readonly call instead of a store.
57
58 ; CHECK:      define void @test3(i8** %p) {
59 ; CHECK-NEXT:   %x = call i8* @objc_loadWeak(i8** %p)
60 ; CHECK-NEXT:   call void @use_pointer(i8* %x) [[RO:#[0-9]+]]
61 ; CHECK-NEXT:   %1 = tail call i8* @objc_retain(i8* %x)
62 ; CHECK-NEXT:   call void @use_pointer(i8* %x)
63 ; CHECK-NEXT:   ret void
64 ; CHECK-NEXT: }
65 define void @test3(i8** %p) {
66   %x = call i8* @objc_loadWeak(i8** %p)
67   call void @use_pointer(i8* %x) readonly
68   %y = call i8* @objc_loadWeakRetained(i8** %p)
69   call void @use_pointer(i8* %y)
70   ret void
71 }
72
73 ; A regular call blocks redundant weak load elimination.
74
75 ; CHECK:      define void @test4(i8** %p) {
76 ; CHECK-NEXT:   %x = call i8* @objc_loadWeak(i8** %p)
77 ; CHECK-NEXT:   call void @use_pointer(i8* %x) [[RO]]
78 ; CHECK-NEXT:   call void @callee()
79 ; CHECK-NEXT:   %y = call i8* @objc_loadWeak(i8** %p)
80 ; CHECK-NEXT:   call void @use_pointer(i8* %y)
81 ; CHECK-NEXT:   ret void
82 ; CHECK-NEXT: }
83 define void @test4(i8** %p) {
84   %x = call i8* @objc_loadWeak(i8** %p)
85   call void @use_pointer(i8* %x) readonly
86   call void @callee()
87   %y = call i8* @objc_loadWeak(i8** %p)
88   call void @use_pointer(i8* %y)
89   ret void
90 }
91
92 ; Store to load forwarding.
93
94 ; CHECK:      define void @test5(i8** %p, i8* %n) {
95 ; CHECK-NEXT:   %1 = call i8* @objc_storeWeak(i8** %p, i8* %n)
96 ; CHECK-NEXT:   call void @use_pointer(i8* %n)
97 ; CHECK-NEXT:   ret void
98 ; CHECK-NEXT: }
99 define void @test5(i8** %p, i8* %n) {
100   call i8* @objc_storeWeak(i8** %p, i8* %n)
101   %y = call i8* @objc_loadWeak(i8** %p)
102   call void @use_pointer(i8* %y)
103   ret void
104 }
105
106 ; Store to load forwarding with objc_initWeak.
107
108 ; CHECK:      define void @test6(i8** %p, i8* %n) {
109 ; CHECK-NEXT:   %1 = call i8* @objc_initWeak(i8** %p, i8* %n)
110 ; CHECK-NEXT:   call void @use_pointer(i8* %n)
111 ; CHECK-NEXT:   ret void
112 ; CHECK-NEXT: }
113 define void @test6(i8** %p, i8* %n) {
114   call i8* @objc_initWeak(i8** %p, i8* %n)
115   %y = call i8* @objc_loadWeak(i8** %p)
116   call void @use_pointer(i8* %y)
117   ret void
118 }
119
120 ; Don't forward if there's a may-alias store in the way.
121
122 ; CHECK:      define void @test7(i8** %p, i8* %n, i8** %q, i8* %m) {
123 ; CHECK-NEXT:   call i8* @objc_initWeak(i8** %p, i8* %n)
124 ; CHECK-NEXT:   call i8* @objc_storeWeak(i8** %q, i8* %m)
125 ; CHECK-NEXT:   %y = call i8* @objc_loadWeak(i8** %p)
126 ; CHECK-NEXT:   call void @use_pointer(i8* %y)
127 ; CHECK-NEXT:   ret void
128 ; CHECK-NEXT: }
129 define void @test7(i8** %p, i8* %n, i8** %q, i8* %m) {
130   call i8* @objc_initWeak(i8** %p, i8* %n)
131   call i8* @objc_storeWeak(i8** %q, i8* %m)
132   %y = call i8* @objc_loadWeak(i8** %p)
133   call void @use_pointer(i8* %y)
134   ret void
135 }
136
137 ; CHECK: attributes #0 = { nounwind }
138 ; CHECK: attributes [[RO]] = { readonly }