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