1 ; RUN: opt -S -basicaa -objc-arc < %s | FileCheck %s
3 declare i8* @llvm.objc.loadWeak(i8**)
4 declare i8* @llvm.objc.loadWeakRetained(i8**)
5 declare i8* @llvm.objc.storeWeak(i8**, i8*)
6 declare i8* @llvm.objc.initWeak(i8**, i8*)
7 declare void @use_pointer(i8*)
10 ; Basic redundant @llvm.objc.loadWeak elimination.
12 ; CHECK: define void @test0(i8** %p) {
13 ; CHECK-NEXT: %y = call i8* @llvm.objc.loadWeak(i8** %p)
14 ; CHECK-NEXT: call void @use_pointer(i8* %y)
15 ; CHECK-NEXT: ret void
17 define void @test0(i8** %p) {
18 %x = call i8* @llvm.objc.loadWeak(i8** %p)
19 %y = call i8* @llvm.objc.loadWeak(i8** %p)
20 call void @use_pointer(i8* %y)
24 ; DCE the @llvm.objc.loadWeak.
26 ; CHECK: define void @test1(i8** %p) {
27 ; CHECK-NEXT: %y = call i8* @llvm.objc.loadWeakRetained(i8** %p)
28 ; CHECK-NEXT: call void @use_pointer(i8* %y)
29 ; CHECK-NEXT: ret void
31 define void @test1(i8** %p) {
32 %x = call i8* @llvm.objc.loadWeak(i8** %p)
33 %y = call i8* @llvm.objc.loadWeakRetained(i8** %p)
34 call void @use_pointer(i8* %y)
38 ; Basic redundant @llvm.objc.loadWeakRetained elimination.
40 ; CHECK: define void @test2(i8** %p) {
41 ; CHECK-NEXT: %x = call i8* @llvm.objc.loadWeak(i8** %p)
42 ; CHECK-NEXT: store i8 3, i8* %x
43 ; CHECK-NEXT: %1 = tail call i8* @llvm.objc.retain(i8* %x)
44 ; CHECK-NEXT: call void @use_pointer(i8* %x)
45 ; CHECK-NEXT: ret void
47 define void @test2(i8** %p) {
48 %x = call i8* @llvm.objc.loadWeak(i8** %p)
50 %y = call i8* @llvm.objc.loadWeakRetained(i8** %p)
51 call void @use_pointer(i8* %y)
55 ; Basic redundant @llvm.objc.loadWeakRetained elimination, this time
56 ; with a readonly call instead of a store.
58 ; CHECK: define void @test3(i8** %p) {
59 ; CHECK-NEXT: %x = call i8* @llvm.objc.loadWeak(i8** %p)
60 ; CHECK-NEXT: call void @use_pointer(i8* %x) [[RO:#[0-9]+]]
61 ; CHECK-NEXT: %1 = tail call i8* @llvm.objc.retain(i8* %x)
62 ; CHECK-NEXT: call void @use_pointer(i8* %x)
63 ; CHECK-NEXT: ret void
65 define void @test3(i8** %p) {
66 %x = call i8* @llvm.objc.loadWeak(i8** %p)
67 call void @use_pointer(i8* %x) readonly
68 %y = call i8* @llvm.objc.loadWeakRetained(i8** %p)
69 call void @use_pointer(i8* %y)
73 ; A regular call blocks redundant weak load elimination.
75 ; CHECK: define void @test4(i8** %p) {
76 ; CHECK-NEXT: %x = call i8* @llvm.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* @llvm.objc.loadWeak(i8** %p)
80 ; CHECK-NEXT: call void @use_pointer(i8* %y)
81 ; CHECK-NEXT: ret void
83 define void @test4(i8** %p) {
84 %x = call i8* @llvm.objc.loadWeak(i8** %p)
85 call void @use_pointer(i8* %x) readonly
87 %y = call i8* @llvm.objc.loadWeak(i8** %p)
88 call void @use_pointer(i8* %y)
92 ; Store to load forwarding.
94 ; CHECK: define void @test5(i8** %p, i8* %n) {
95 ; CHECK-NEXT: %1 = call i8* @llvm.objc.storeWeak(i8** %p, i8* %n)
96 ; CHECK-NEXT: call void @use_pointer(i8* %n)
97 ; CHECK-NEXT: ret void
99 define void @test5(i8** %p, i8* %n) {
100 call i8* @llvm.objc.storeWeak(i8** %p, i8* %n)
101 %y = call i8* @llvm.objc.loadWeak(i8** %p)
102 call void @use_pointer(i8* %y)
106 ; Store to load forwarding with objc_initWeak.
108 ; CHECK: define void @test6(i8** %p, i8* %n) {
109 ; CHECK-NEXT: %1 = call i8* @llvm.objc.initWeak(i8** %p, i8* %n)
110 ; CHECK-NEXT: call void @use_pointer(i8* %n)
111 ; CHECK-NEXT: ret void
113 define void @test6(i8** %p, i8* %n) {
114 call i8* @llvm.objc.initWeak(i8** %p, i8* %n)
115 %y = call i8* @llvm.objc.loadWeak(i8** %p)
116 call void @use_pointer(i8* %y)
120 ; Don't forward if there's a may-alias store in the way.
122 ; CHECK: define void @test7(i8** %p, i8* %n, i8** %q, i8* %m) {
123 ; CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** %p, i8* %n)
124 ; CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** %q, i8* %m)
125 ; CHECK-NEXT: %y = call i8* @llvm.objc.loadWeak(i8** %p)
126 ; CHECK-NEXT: call void @use_pointer(i8* %y)
127 ; CHECK-NEXT: ret void
129 define void @test7(i8** %p, i8* %n, i8** %q, i8* %m) {
130 call i8* @llvm.objc.initWeak(i8** %p, i8* %n)
131 call i8* @llvm.objc.storeWeak(i8** %q, i8* %m)
132 %y = call i8* @llvm.objc.loadWeak(i8** %p)
133 call void @use_pointer(i8* %y)
137 ; CHECK: attributes #0 = { nounwind }
138 ; CHECK: attributes [[RO]] = { readonly }